diff options
author | Sascha Hauer <sha@octopus.labnet.pengutronix.de> | 2007-09-21 14:02:08 +0200 |
---|---|---|
committer | Sascha Hauer <sha@octopus.labnet.pengutronix.de> | 2007-09-21 14:02:08 +0200 |
commit | 9a365ade16d8f489d223a6c960fa494d8012422b (patch) | |
tree | 2242afdaf9a602f442c912d236fce4ddb7b5b94d /fs | |
parent | a83669c197bb27684ed66cd1bfeafb2e5c4a6ccc (diff) | |
download | barebox-9a365ade16d8f489d223a6c960fa494d8012422b.tar.gz barebox-9a365ade16d8f489d223a6c960fa494d8012422b.tar.xz |
remove uncompilable filesystems
Diffstat (limited to 'fs')
31 files changed, 0 insertions, 9701 deletions
diff --git a/fs/ext2/Makefile b/fs/ext2/Makefile deleted file mode 100644 index 8313cdc17c..0000000000 --- a/fs/ext2/Makefile +++ /dev/null @@ -1,52 +0,0 @@ -# -# (C) Copyright 2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# (C) Copyright 2003 -# Pavel Bartusek, Sysgo Real-Time Solutions AG, pba@sysgo.de -# -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)libext2fs.a - -AOBJS = -COBJS = ext2fs.o dev.o - -SRCS := $(AOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(AOBJS) $(COBJS)) - -#CPPFLAGS += - -all: $(LIB) $(AOBJS) - -$(LIB): $(obj).depend $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/fs/ext2/dev.c b/fs/ext2/dev.c deleted file mode 100644 index 1469e982b7..0000000000 --- a/fs/ext2/dev.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * (C) Copyright 2004 - * esd gmbh <www.esd-electronics.com> - * Reinhard Arlt <reinhard.arlt@esd-electronics.com> - * - * based on code of fs/reiserfs/dev.c by - * - * (C) Copyright 2003 - 2004 - * Sysgo AG, <www.elinos.com>, Pavel Bartusek <pba@sysgo.com> - * - * 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 <common.h> -#if (CONFIG_COMMANDS & CFG_CMD_EXT2) - -#include <config.h> -#include <ext2fs.h> - -static block_dev_desc_t *ext2fs_block_dev_desc; -static disk_partition_t part_info; - -int ext2fs_set_blk_dev (block_dev_desc_t * rbdd, int part) -{ - ext2fs_block_dev_desc = rbdd; - - if (part == 0) { - /* disk doesn't use partition table */ - part_info.start = 0; - part_info.size = rbdd->lba; - part_info.blksz = rbdd->blksz; - } else { - if (get_partition_info - (ext2fs_block_dev_desc, part, &part_info)) { - return 0; - } - } - return (part_info.size); -} - - -int ext2fs_devread (int sector, int byte_offset, int byte_len, char *buf) { - char sec_buf[SECTOR_SIZE]; - unsigned block_len; - -/* - * Check partition boundaries - */ - if ((sector < 0) - || ((sector + ((byte_offset + byte_len - 1) >> SECTOR_BITS)) >= - part_info.size)) { - /* errnum = ERR_OUTSIDE_PART; */ - printf (" ** ext2fs_devread() read outside partition sector %d\n", sector); - return (0); - } - -/* - * Get the read to the beginning of a partition. - */ - sector += byte_offset >> SECTOR_BITS; - byte_offset &= SECTOR_SIZE - 1; - - debug (" <%d, %d, %d>\n", sector, byte_offset, byte_len); - - if (ext2fs_block_dev_desc == NULL) { - printf ("** Invalid Block Device Descriptor (NULL)\n"); - return (0); - } - - if (byte_offset != 0) { - /* read first part which isn't aligned with start of sector */ - if (ext2fs_block_dev_desc-> - block_read (ext2fs_block_dev_desc->dev, - part_info.start + sector, 1, - (unsigned long *) sec_buf) != 1) { - printf (" ** ext2fs_devread() read error **\n"); - return (0); - } - memcpy (buf, sec_buf + byte_offset, - min (SECTOR_SIZE - byte_offset, byte_len)); - buf += min (SECTOR_SIZE - byte_offset, byte_len); - byte_len -= min (SECTOR_SIZE - byte_offset, byte_len); - sector++; - } - - /* read sector aligned part */ - block_len = byte_len & ~(SECTOR_SIZE - 1); - if (ext2fs_block_dev_desc->block_read (ext2fs_block_dev_desc->dev, - part_info.start + sector, - block_len / SECTOR_SIZE, - (unsigned long *) buf) != - block_len / SECTOR_SIZE) { - printf (" ** ext2fs_devread() read error - block\n"); - return (0); - } - buf += block_len; - byte_len -= block_len; - sector += block_len / SECTOR_SIZE; - - if (byte_len != 0) { - /* read rest of data which are not in whole sector */ - if (ext2fs_block_dev_desc-> - block_read (ext2fs_block_dev_desc->dev, - part_info.start + sector, 1, - (unsigned long *) sec_buf) != 1) { - printf (" ** ext2fs_devread() read error - last part\n"); - return (0); - } - memcpy (buf, sec_buf, byte_len); - } - return (1); -} -#endif /* CFG_CMD_EXT2FS */ diff --git a/fs/ext2/ext2fs.c b/fs/ext2/ext2fs.c deleted file mode 100644 index 9cf2fb7ba4..0000000000 --- a/fs/ext2/ext2fs.c +++ /dev/null @@ -1,878 +0,0 @@ -/* - * (C) Copyright 2004 - * esd gmbh <www.esd-electronics.com> - * Reinhard Arlt <reinhard.arlt@esd-electronics.com> - * - * based on code from grub2 fs/ext2.c and fs/fshelp.c by - * - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2003, 2004 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 <common.h> - -#if (CONFIG_COMMANDS & CFG_CMD_EXT2) -#include <ext2fs.h> -#include <malloc.h> -#include <asm/byteorder.h> - -extern int ext2fs_devread (int sector, int byte_offset, int byte_len, - char *buf); - -/* Magic value used to identify an ext2 filesystem. */ -#define EXT2_MAGIC 0xEF53 -/* Amount of indirect blocks in an inode. */ -#define INDIRECT_BLOCKS 12 -/* Maximum lenght of a pathname. */ -#define EXT2_PATH_MAX 4096 -/* Maximum nesting of symlinks, used to prevent a loop. */ -#define EXT2_MAX_SYMLINKCNT 8 - -/* Filetype used in directory entry. */ -#define FILETYPE_UNKNOWN 0 -#define FILETYPE_REG 1 -#define FILETYPE_DIRECTORY 2 -#define FILETYPE_SYMLINK 7 - -/* Filetype information as used in inodes. */ -#define FILETYPE_INO_MASK 0170000 -#define FILETYPE_INO_REG 0100000 -#define FILETYPE_INO_DIRECTORY 0040000 -#define FILETYPE_INO_SYMLINK 0120000 - -/* Bits used as offset in sector */ -#define DISK_SECTOR_BITS 9 - -/* Log2 size of ext2 block in 512 blocks. */ -#define LOG2_EXT2_BLOCK_SIZE(data) (__le32_to_cpu (data->sblock.log2_block_size) + 1) - -/* Log2 size of ext2 block in bytes. */ -#define LOG2_BLOCK_SIZE(data) (__le32_to_cpu (data->sblock.log2_block_size) + 10) - -/* The size of an ext2 block in bytes. */ -#define EXT2_BLOCK_SIZE(data) (1 << LOG2_BLOCK_SIZE(data)) - -/* The ext2 superblock. */ -struct ext2_sblock { - uint32_t total_inodes; - uint32_t total_blocks; - uint32_t reserved_blocks; - uint32_t free_blocks; - uint32_t free_inodes; - uint32_t first_data_block; - uint32_t log2_block_size; - uint32_t log2_fragment_size; - uint32_t blocks_per_group; - uint32_t fragments_per_group; - uint32_t inodes_per_group; - uint32_t mtime; - uint32_t utime; - uint16_t mnt_count; - uint16_t max_mnt_count; - uint16_t magic; - uint16_t fs_state; - uint16_t error_handling; - uint16_t minor_revision_level; - uint32_t lastcheck; - uint32_t checkinterval; - uint32_t creator_os; - uint32_t revision_level; - uint16_t uid_reserved; - uint16_t gid_reserved; - uint32_t first_inode; - uint16_t inode_size; - uint16_t block_group_number; - uint32_t feature_compatibility; - uint32_t feature_incompat; - uint32_t feature_ro_compat; - uint32_t unique_id[4]; - char volume_name[16]; - char last_mounted_on[64]; - uint32_t compression_info; -}; - -/* The ext2 blockgroup. */ -struct ext2_block_group { - uint32_t block_id; - uint32_t inode_id; - uint32_t inode_table_id; - uint16_t free_blocks; - uint16_t free_inodes; - uint16_t pad; - uint32_t reserved[3]; -}; - -/* The ext2 inode. */ -struct ext2_inode { - uint16_t mode; - uint16_t uid; - uint32_t size; - uint32_t atime; - uint32_t ctime; - uint32_t mtime; - uint32_t dtime; - uint16_t gid; - uint16_t nlinks; - uint32_t blockcnt; /* Blocks of 512 bytes!! */ - uint32_t flags; - uint32_t osd1; - union { - struct datablocks { - uint32_t dir_blocks[INDIRECT_BLOCKS]; - uint32_t indir_block; - uint32_t double_indir_block; - uint32_t tripple_indir_block; - } blocks; - char symlink[60]; - } b; - uint32_t version; - uint32_t acl; - uint32_t dir_acl; - uint32_t fragment_addr; - uint32_t osd2[3]; -}; - -/* The header of an ext2 directory entry. */ -struct ext2_dirent { - uint32_t inode; - uint16_t direntlen; - uint8_t namelen; - uint8_t filetype; -}; - -struct ext2fs_node { - struct ext2_data *data; - struct ext2_inode inode; - int ino; - int inode_read; -}; - -/* Information about a "mounted" ext2 filesystem. */ -struct ext2_data { - struct ext2_sblock sblock; - struct ext2_inode *inode; - struct ext2fs_node diropen; -}; - - -typedef struct ext2fs_node *ext2fs_node_t; - -struct ext2_data *ext2fs_root = NULL; -ext2fs_node_t ext2fs_file = NULL; -int symlinknest = 0; -uint32_t *indir1_block = NULL; -int indir1_size = 0; -int indir1_blkno = -1; -uint32_t *indir2_block = NULL; -int indir2_size = 0; -int indir2_blkno = -1; - - -static int ext2fs_blockgroup - (struct ext2_data *data, int group, struct ext2_block_group *blkgrp) { -#ifdef DEBUG - printf ("ext2fs read blockgroup\n"); -#endif - return (ext2fs_devread - (((__le32_to_cpu (data->sblock.first_data_block) + - 1) << LOG2_EXT2_BLOCK_SIZE (data)), - group * sizeof (struct ext2_block_group), - sizeof (struct ext2_block_group), (char *) blkgrp)); -} - - -static int ext2fs_read_inode - (struct ext2_data *data, int ino, struct ext2_inode *inode) { - struct ext2_block_group blkgrp; - struct ext2_sblock *sblock = &data->sblock; - int inodes_per_block; - int status; - - unsigned int blkno; - unsigned int blkoff; - - /* It is easier to calculate if the first inode is 0. */ - ino--; -#ifdef DEBUG - printf ("ext2fs read inode %d\n", ino); -#endif - status = ext2fs_blockgroup (data, - ino / - __le32_to_cpu (sblock->inodes_per_group), - &blkgrp); - if (status == 0) { - return (0); - } - inodes_per_block = EXT2_BLOCK_SIZE (data) / 128; - blkno = (ino % __le32_to_cpu (sblock->inodes_per_group)) / - inodes_per_block; - blkoff = (ino % __le32_to_cpu (sblock->inodes_per_group)) % - inodes_per_block; -#ifdef DEBUG - printf ("ext2fs read inode blkno %d blkoff %d\n", blkno, blkoff); -#endif - /* Read the inode. */ - status = ext2fs_devread (((__le32_to_cpu (blkgrp.inode_table_id) + - blkno) << LOG2_EXT2_BLOCK_SIZE (data)), - sizeof (struct ext2_inode) * blkoff, - sizeof (struct ext2_inode), (char *) inode); - if (status == 0) { - return (0); - } - return (1); -} - - -void ext2fs_free_node (ext2fs_node_t node, ext2fs_node_t currroot) { - if ((node != &ext2fs_root->diropen) && (node != currroot)) { - free (node); - } -} - - -static int ext2fs_read_block (ext2fs_node_t node, int fileblock) { - struct ext2_data *data = node->data; - struct ext2_inode *inode = &node->inode; - int blknr; - int blksz = EXT2_BLOCK_SIZE (data); - int log2_blksz = LOG2_EXT2_BLOCK_SIZE (data); - int status; - - /* Direct blocks. */ - if (fileblock < INDIRECT_BLOCKS) { - blknr = __le32_to_cpu (inode->b.blocks.dir_blocks[fileblock]); - } - /* Indirect. */ - else if (fileblock < (INDIRECT_BLOCKS + (blksz / 4))) { - if (indir1_block == NULL) { - indir1_block = (uint32_t *) malloc (blksz); - if (indir1_block == NULL) { - printf ("** ext2fs read block (indir 1) malloc failed. **\n"); - return (-1); - } - indir1_size = blksz; - indir1_blkno = -1; - } - if (blksz != indir1_size) { - free (indir1_block); - indir1_block = NULL; - indir1_size = 0; - indir1_blkno = -1; - indir1_block = (uint32_t *) malloc (blksz); - if (indir1_block == NULL) { - printf ("** ext2fs read block (indir 1) malloc failed. **\n"); - return (-1); - } - indir1_size = blksz; - } - if ((__le32_to_cpu (inode->b.blocks.indir_block) << - log2_blksz) != indir1_blkno) { - status = ext2fs_devread (__le32_to_cpu(inode->b.blocks.indir_block) << log2_blksz, - 0, blksz, - (char *) indir1_block); - if (status == 0) { - printf ("** ext2fs read block (indir 1) failed. **\n"); - return (0); - } - indir1_blkno = - __le32_to_cpu (inode->b.blocks. - indir_block) << log2_blksz; - } - blknr = __le32_to_cpu (indir1_block - [fileblock - INDIRECT_BLOCKS]); - } - /* Double indirect. */ - else if (fileblock < - (INDIRECT_BLOCKS + (blksz / 4 * (blksz / 4 + 1)))) { - unsigned int perblock = blksz / 4; - unsigned int rblock = fileblock - (INDIRECT_BLOCKS - + blksz / 4); - - if (indir1_block == NULL) { - indir1_block = (uint32_t *) malloc (blksz); - if (indir1_block == NULL) { - printf ("** ext2fs read block (indir 2 1) malloc failed. **\n"); - return (-1); - } - indir1_size = blksz; - indir1_blkno = -1; - } - if (blksz != indir1_size) { - free (indir1_block); - indir1_block = NULL; - indir1_size = 0; - indir1_blkno = -1; - indir1_block = (uint32_t *) malloc (blksz); - if (indir1_block == NULL) { - printf ("** ext2fs read block (indir 2 1) malloc failed. **\n"); - return (-1); - } - indir1_size = blksz; - } - if ((__le32_to_cpu (inode->b.blocks.double_indir_block) << - log2_blksz) != indir1_blkno) { - status = ext2fs_devread (__le32_to_cpu(inode->b.blocks.double_indir_block) << log2_blksz, - 0, blksz, - (char *) indir1_block); - if (status == 0) { - printf ("** ext2fs read block (indir 2 1) failed. **\n"); - return (-1); - } - indir1_blkno = - __le32_to_cpu (inode->b.blocks.double_indir_block) << log2_blksz; - } - - if (indir2_block == NULL) { - indir2_block = (uint32_t *) malloc (blksz); - if (indir2_block == NULL) { - printf ("** ext2fs read block (indir 2 2) malloc failed. **\n"); - return (-1); - } - indir2_size = blksz; - indir2_blkno = -1; - } - if (blksz != indir2_size) { - free (indir2_block); - indir2_block = NULL; - indir2_size = 0; - indir2_blkno = -1; - indir2_block = (uint32_t *) malloc (blksz); - if (indir2_block == NULL) { - printf ("** ext2fs read block (indir 2 2) malloc failed. **\n"); - return (-1); - } - indir2_size = blksz; - } - if ((__le32_to_cpu (indir1_block[rblock / perblock]) << - log2_blksz) != indir1_blkno) { - status = ext2fs_devread (__le32_to_cpu(indir1_block[rblock / perblock]) << log2_blksz, - 0, blksz, - (char *) indir2_block); - if (status == 0) { - printf ("** ext2fs read block (indir 2 2) failed. **\n"); - return (-1); - } - indir2_blkno = - __le32_to_cpu (indir1_block[rblock / perblock]) << log2_blksz; - } - blknr = __le32_to_cpu (indir2_block[rblock % perblock]); - } - /* Tripple indirect. */ - else { - printf ("** ext2fs doesn't support tripple indirect blocks. **\n"); - return (-1); - } -#ifdef DEBUG - printf ("ext2fs_read_block %08x\n", blknr); -#endif - return (blknr); -} - - -int ext2fs_read_file - (ext2fs_node_t node, int pos, unsigned int len, char *buf) { - int i; - int blockcnt; - int log2blocksize = LOG2_EXT2_BLOCK_SIZE (node->data); - int blocksize = 1 << (log2blocksize + DISK_SECTOR_BITS); - unsigned int filesize = __le32_to_cpu(node->inode.size); - - /* Adjust len so it we can't read past the end of the file. */ - if (len > filesize) { - len = filesize; - } - blockcnt = ((len + pos) + blocksize - 1) / blocksize; - - for (i = pos / blocksize; i < blockcnt; i++) { - int blknr; - int blockoff = pos % blocksize; - int blockend = blocksize; - - int skipfirst = 0; - - blknr = ext2fs_read_block (node, i); - if (blknr < 0) { - return (-1); - } - blknr = blknr << log2blocksize; - - /* Last block. */ - if (i == blockcnt - 1) { - blockend = (len + pos) % blocksize; - - /* The last portion is exactly blocksize. */ - if (!blockend) { - blockend = blocksize; - } - } - - /* First block. */ - if (i == pos / blocksize) { - skipfirst = blockoff; - blockend -= skipfirst; - } - - /* If the block number is 0 this block is not stored on disk but - is zero filled instead. */ - if (blknr) { - int status; - - status = ext2fs_devread (blknr, skipfirst, blockend, buf); - if (status == 0) { - return (-1); - } - } else { - memset (buf, blocksize - skipfirst, 0); - } - buf += blocksize - skipfirst; - } - return (len); -} - - -static int ext2fs_iterate_dir (ext2fs_node_t dir, char *name, ext2fs_node_t * fnode, int *ftype) -{ - unsigned int fpos = 0; - int status; - struct ext2fs_node *diro = (struct ext2fs_node *) dir; - -#ifdef DEBUG - if (name != NULL) - printf ("Iterate dir %s\n", name); -#endif /* of DEBUG */ - if (!diro->inode_read) { - status = ext2fs_read_inode (diro->data, diro->ino, - &diro->inode); - if (status == 0) { - return (0); - } - } - /* Search the file. */ - while (fpos < __le32_to_cpu (diro->inode.size)) { - struct ext2_dirent dirent; - - status = ext2fs_read_file (diro, fpos, - sizeof (struct ext2_dirent), - (char *) &dirent); - if (status < 1) { - return (0); - } - if (dirent.namelen != 0) { - char filename[dirent.namelen + 1]; - ext2fs_node_t fdiro; - int type = FILETYPE_UNKNOWN; - - status = ext2fs_read_file (diro, - fpos + sizeof (struct ext2_dirent), - dirent.namelen, filename); - if (status < 1) { - return (0); - } - fdiro = malloc (sizeof (struct ext2fs_node)); - if (!fdiro) { - return (0); - } - - fdiro->data = diro->data; - fdiro->ino = __le32_to_cpu (dirent.inode); - - filename[dirent.namelen] = '\0'; - - if (dirent.filetype != FILETYPE_UNKNOWN) { - fdiro->inode_read = 0; - - if (dirent.filetype == FILETYPE_DIRECTORY) { - type = FILETYPE_DIRECTORY; - } else if (dirent.filetype == - FILETYPE_SYMLINK) { - type = FILETYPE_SYMLINK; - } else if (dirent.filetype == FILETYPE_REG) { - type = FILETYPE_REG; - } - } else { - /* The filetype can not be read from the dirent, get it from inode */ - - status = ext2fs_read_inode (diro->data, - __le32_to_cpu(dirent.inode), - &fdiro->inode); - if (status == 0) { - free (fdiro); - return (0); - } - fdiro->inode_read = 1; - - if ((__le16_to_cpu (fdiro->inode.mode) & - FILETYPE_INO_MASK) == - FILETYPE_INO_DIRECTORY) { - type = FILETYPE_DIRECTORY; - } else if ((__le16_to_cpu (fdiro->inode.mode) - & FILETYPE_INO_MASK) == - FILETYPE_INO_SYMLINK) { - type = FILETYPE_SYMLINK; - } else if ((__le16_to_cpu (fdiro->inode.mode) - & FILETYPE_INO_MASK) == - FILETYPE_INO_REG) { - type = FILETYPE_REG; - } - } -#ifdef DEBUG - printf ("iterate >%s<\n", filename); -#endif /* of DEBUG */ - if ((name != NULL) && (fnode != NULL) - && (ftype != NULL)) { - if (strcmp (filename, name) == 0) { - *ftype = type; - *fnode = fdiro; - return (1); - } - } else { - if (fdiro->inode_read == 0) { - status = ext2fs_read_inode (diro->data, - __le32_to_cpu (dirent.inode), - &fdiro->inode); - if (status == 0) { - free (fdiro); - return (0); - } - fdiro->inode_read = 1; - } - switch (type) { - case FILETYPE_DIRECTORY: - printf ("<DIR> "); - break; - case FILETYPE_SYMLINK: - printf ("<SYM> "); - break; - case FILETYPE_REG: - printf (" "); - break; - default: - printf ("< ? > "); - break; - } - printf ("%10d %s\n", - __le32_to_cpu (fdiro->inode.size), - filename); - } - free (fdiro); - } - fpos += __le16_to_cpu (dirent.direntlen); - } - return (0); -} - - -static char *ext2fs_read_symlink (ext2fs_node_t node) { - char *symlink; - struct ext2fs_node *diro = node; - int status; - - if (!diro->inode_read) { - status = ext2fs_read_inode (diro->data, diro->ino, - &diro->inode); - if (status == 0) { - return (0); - } - } - symlink = malloc (__le32_to_cpu (diro->inode.size) + 1); - if (!symlink) { - return (0); - } - /* If the filesize of the symlink is bigger than - 60 the symlink is stored in a separate block, - otherwise it is stored in the inode. */ - if (__le32_to_cpu (diro->inode.size) <= 60) { - strncpy (symlink, diro->inode.b.symlink, - __le32_to_cpu (diro->inode.size)); - } else { - status = ext2fs_read_file (diro, 0, - __le32_to_cpu (diro->inode.size), - symlink); - if (status == 0) { - free (symlink); - return (0); - } - } - symlink[__le32_to_cpu (diro->inode.size)] = '\0'; - return (symlink); -} - - -int ext2fs_find_file1 - (const char *currpath, - ext2fs_node_t currroot, ext2fs_node_t * currfound, int *foundtype) { - char fpath[strlen (currpath) + 1]; - char *name = fpath; - char *next; - int status; - int type = FILETYPE_DIRECTORY; - ext2fs_node_t currnode = currroot; - ext2fs_node_t oldnode = currroot; - - strncpy (fpath, currpath, strlen (currpath) + 1); - - /* Remove all leading slashes. */ - while (*name == '/') { - name++; - } - if (!*name) { - *currfound = currnode; - return (1); - } - - for (;;) { - int found; - - /* Extract the actual part from the pathname. */ - next = strchr (name, '/'); - if (next) { - /* Remove all leading slashes. */ - while (*next == '/') { - *(next++) = '\0'; - } - } - - /* At this point it is expected that the current node is a directory, check if this is true. */ - if (type != FILETYPE_DIRECTORY) { - ext2fs_free_node (currnode, currroot); - return (0); - } - - oldnode = currnode; - - /* Iterate over the directory. */ - found = ext2fs_iterate_dir (currnode, name, &currnode, &type); - if (found == 0) { - return (0); - } - if (found == -1) { - break; - } - - /* Read in the symlink and follow it. */ - if (type == FILETYPE_SYMLINK) { - char *symlink; - - /* Test if the symlink does not loop. */ - if (++symlinknest == 8) { - ext2fs_free_node (currnode, currroot); - ext2fs_free_node (oldnode, currroot); - return (0); - } - - symlink = ext2fs_read_symlink (currnode); - ext2fs_free_node (currnode, currroot); - - if (!symlink) { - ext2fs_free_node (oldnode, currroot); - return (0); - } -#ifdef DEBUG - printf ("Got symlink >%s<\n", symlink); -#endif /* of DEBUG */ - /* The symlink is an absolute path, go back to the root inode. */ - if (symlink[0] == '/') { - ext2fs_free_node (oldnode, currroot); - oldnode = &ext2fs_root->diropen; - } - - /* Lookup the node the symlink points to. */ - status = ext2fs_find_file1 (symlink, oldnode, - &currnode, &type); - - free (symlink); - - if (status == 0) { - ext2fs_free_node (oldnode, currroot); - return (0); - } - } - - ext2fs_free_node (oldnode, currroot); - - /* Found the node! */ - if (!next || *next == '\0') { - *currfound = currnode; - *foundtype = type; - return (1); - } - name = next; - } - return (-1); -} - - -int ext2fs_find_file - (const char *path, - ext2fs_node_t rootnode, ext2fs_node_t * foundnode, int expecttype) { - int status; - int foundtype = FILETYPE_DIRECTORY; - - - symlinknest = 0; - if (!path) { - return (0); - } - - status = ext2fs_find_file1 (path, rootnode, foundnode, &foundtype); - if (status == 0) { - return (0); - } - /* Check if the node that was found was of the expected type. */ - if ((expecttype == FILETYPE_REG) && (foundtype != expecttype)) { - return (0); - } else if ((expecttype == FILETYPE_DIRECTORY) - && (foundtype != expecttype)) { - return (0); - } - return (1); -} - - -int ext2fs_ls (char *dirname) { - ext2fs_node_t dirnode; - int status; - - if (ext2fs_root == NULL) { - return (0); - } - - status = ext2fs_find_file (dirname, &ext2fs_root->diropen, &dirnode, - FILETYPE_DIRECTORY); - if (status != 1) { - printf ("** Can not find directory. **\n"); - return (1); - } - ext2fs_iterate_dir (dirnode, NULL, NULL, NULL); - ext2fs_free_node (dirnode, &ext2fs_root->diropen); - return (0); -} - - -int ext2fs_open (char *filename) { - ext2fs_node_t fdiro = NULL; - int status; - int len; - - if (ext2fs_root == NULL) { - return (-1); - } - ext2fs_file = NULL; - status = ext2fs_find_file (filename, &ext2fs_root->diropen, &fdiro, - FILETYPE_REG); - if (status == 0) { - goto fail; - } - if (!fdiro->inode_read) { - status = ext2fs_read_inode (fdiro->data, fdiro->ino, - &fdiro->inode); - if (status == 0) { - goto fail; - } - } - len = __le32_to_cpu (fdiro->inode.size); - ext2fs_file = fdiro; - return (len); - -fail: - ext2fs_free_node (fdiro, &ext2fs_root->diropen); - return (-1); -} - - -int ext2fs_close (void - ) { - if ((ext2fs_file != NULL) && (ext2fs_root != NULL)) { - ext2fs_free_node (ext2fs_file, &ext2fs_root->diropen); - ext2fs_file = NULL; - } - if (ext2fs_root != NULL) { - free (ext2fs_root); - ext2fs_root = NULL; - } - if (indir1_block != NULL) { - free (indir1_block); - indir1_block = NULL; - indir1_size = 0; - indir1_blkno = -1; - } - if (indir2_block != NULL) { - free (indir2_block); - indir2_block = NULL; - indir2_size = 0; - indir2_blkno = -1; - } - return (0); -} - - -int ext2fs_read (char *buf, unsigned len) { - int status; - - if (ext2fs_root == NULL) { - return (0); - } - - if (ext2fs_file == NULL) { - return (0); - } - - status = ext2fs_read_file (ext2fs_file, 0, len, buf); - return (status); -} - - -int ext2fs_mount (unsigned part_length) { - struct ext2_data *data; - int status; - - data = malloc (sizeof (struct ext2_data)); - if (!data) { - return (0); - } - /* Read the superblock. */ - status = ext2fs_devread (1 * 2, 0, sizeof (struct ext2_sblock), - (char *) &data->sblock); - if (status == 0) { - goto fail; - } - /* Make sure this is an ext2 filesystem. */ - if (__le16_to_cpu (data->sblock.magic) != EXT2_MAGIC) { - goto fail; - } - data->diropen.data = data; - data->diropen.ino = 2; - data->diropen.inode_read = 1; - data->inode = &data->diropen.inode; - - status = ext2fs_read_inode (data, 2, data->inode); - if (status == 0) { - goto fail; - } - - ext2fs_root = data; - - return (1); - -fail: - printf ("Failed to mount ext2 filesystem...\n"); - free (data); - ext2fs_root = NULL; - return (0); -} - -#endif /* CFG_CMD_EXT2FS */ diff --git a/fs/fat/Makefile b/fs/fat/Makefile deleted file mode 100644 index 87af73b7eb..0000000000 --- a/fs/fat/Makefile +++ /dev/null @@ -1,45 +0,0 @@ -# -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)libfat.a - -AOBJS = -COBJS = fat.o file.o - -SRCS := $(AOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(AOBJS) $(COBJS)) - -all: $(LIB) $(AOBJS) - -$(LIB): $(obj).depend $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/fs/fat/fat.c b/fs/fat/fat.c deleted file mode 100644 index af9f36abd1..0000000000 --- a/fs/fat/fat.c +++ /dev/null @@ -1,1012 +0,0 @@ -/* - * fat.c - * - * R/O (V)FAT 12/16/32 filesystem implementation by Marcus Sundberg - * - * 2002-07-28 - rjones@nexus-tech.net - ported to ppcboot v1.1.6 - * 2003-03-10 - kharris@nexus-tech.net - ported to uboot - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> -#include <config.h> -#include <fat.h> -#include <asm/byteorder.h> -#include <part.h> - -#if (CONFIG_COMMANDS & CFG_CMD_FAT) - -/* - * Convert a string to lowercase. - */ -static void -downcase(char *str) -{ - while (*str != '\0') { - TOLOWER(*str); - str++; - } -} - -static block_dev_desc_t *cur_dev = NULL; -static unsigned long part_offset = 0; -static int cur_part = 1; - -#define DOS_PART_TBL_OFFSET 0x1be -#define DOS_PART_MAGIC_OFFSET 0x1fe -#define DOS_FS_TYPE_OFFSET 0x36 - -int disk_read (__u32 startblock, __u32 getsize, __u8 * bufptr) -{ - startblock += part_offset; - if (cur_dev == NULL) - return -1; - if (cur_dev->block_read) { - return cur_dev->block_read (cur_dev->dev, startblock, getsize, (unsigned long *)bufptr); - } - return -1; -} - - -int -fat_register_device(block_dev_desc_t *dev_desc, int part_no) -{ - unsigned char buffer[SECTOR_SIZE]; - - if (!dev_desc->block_read) - return -1; - cur_dev=dev_desc; - /* check if we have a MBR (on floppies we have only a PBR) */ - if (dev_desc->block_read (dev_desc->dev, 0, 1, (ulong *) buffer) != 1) { - printf ("** Can't read from device %d **\n", dev_desc->dev); - return -1; - } - if (buffer[DOS_PART_MAGIC_OFFSET] != 0x55 || - buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) { - /* no signature found */ - return -1; - } - if(!strncmp((char *)&buffer[DOS_FS_TYPE_OFFSET],"FAT",3)) { - /* ok, we assume we are on a PBR only */ - cur_part = 1; - part_offset=0; - } - else { -#if (CONFIG_COMMANDS & CFG_CMD_IDE) || (CONFIG_COMMANDS & CFG_CMD_SCSI) || \ - (CONFIG_COMMANDS & CFG_CMD_USB) || defined(CONFIG_SYSTEMACE) - disk_partition_t info; - if(!get_partition_info(dev_desc, part_no, &info)) { - part_offset = info.start; - cur_part = part_no; - } - else { - printf ("** Partition %d not valid on device %d **\n",part_no,dev_desc->dev); - return -1; - } -#else - /* FIXME we need to determine the start block of the - * partition where the DOS FS resides. This can be done - * by using the get_partition_info routine. For this - * purpose the libpart must be included. - */ - part_offset=32; - cur_part = 1; -#endif - } - return 0; -} - - -/* - * Get the first occurence of a directory delimiter ('/' or '\') in a string. - * Return index into string if found, -1 otherwise. - */ -static int -dirdelim(char *str) -{ - char *start = str; - - while (*str != '\0') { - if (ISDIRDELIM(*str)) return str - start; - str++; - } - return -1; -} - - -/* - * Match volume_info fs_type strings. - * Return 0 on match, -1 otherwise. - */ -static int -compare_sign(char *str1, char *str2) -{ - char *end = str1+SIGNLEN; - - while (str1 != end) { - if (*str1 != *str2) { - return -1; - } - str1++; - str2++; - } - - return 0; -} - - -/* - * Extract zero terminated short name from a directory entry. - */ -static void get_name (dir_entry *dirent, char *s_name) -{ - char *ptr; - - memcpy (s_name, dirent->name, 8); - s_name[8] = '\0'; - ptr = s_name; - while (*ptr && *ptr != ' ') - ptr++; - if (dirent->ext[0] && dirent->ext[0] != ' ') { - *ptr = '.'; - ptr++; - memcpy (ptr, dirent->ext, 3); - ptr[3] = '\0'; - while (*ptr && *ptr != ' ') - ptr++; - } - *ptr = '\0'; - if (*s_name == DELETED_FLAG) - *s_name = '\0'; - else if (*s_name == aRING) - *s_name = 'å'; - downcase (s_name); -} - -/* - * Get the entry at index 'entry' in a FAT (12/16/32) table. - * On failure 0x00 is returned. - */ -static __u32 -get_fatent(fsdata *mydata, __u32 entry) -{ - __u32 bufnum; - __u32 offset; - __u32 ret = 0x00; - - switch (mydata->fatsize) { - case 32: - bufnum = entry / FAT32BUFSIZE; - offset = entry - bufnum * FAT32BUFSIZE; - break; - case 16: - bufnum = entry / FAT16BUFSIZE; - offset = entry - bufnum * FAT16BUFSIZE; - break; - case 12: - bufnum = entry / FAT12BUFSIZE; - offset = entry - bufnum * FAT12BUFSIZE; - break; - - default: - /* Unsupported FAT size */ - return ret; - } - - /* Read a new block of FAT entries into the cache. */ - if (bufnum != mydata->fatbufnum) { - int getsize = FATBUFSIZE/FS_BLOCK_SIZE; - __u8 *bufptr = mydata->fatbuf; - __u32 fatlength = mydata->fatlength; - __u32 startblock = bufnum * FATBUFBLOCKS; - - fatlength *= SECTOR_SIZE; /* We want it in bytes now */ - startblock += mydata->fat_sect; /* Offset from start of disk */ - - if (getsize > fatlength) getsize = fatlength; - if (disk_read(startblock, getsize, bufptr) < 0) { - FAT_DPRINT("Error reading FAT blocks\n"); - return ret; - } - mydata->fatbufnum = bufnum; - } - - /* Get the actual entry from the table */ - switch (mydata->fatsize) { - case 32: - ret = FAT2CPU32(((__u32*)mydata->fatbuf)[offset]); - break; - case 16: - ret = FAT2CPU16(((__u16*)mydata->fatbuf)[offset]); - break; - case 12: { - __u32 off16 = (offset*3)/4; - __u16 val1, val2; - - switch (offset & 0x3) { - case 0: - ret = FAT2CPU16(((__u16*)mydata->fatbuf)[off16]); - ret &= 0xfff; - break; - case 1: - val1 = FAT2CPU16(((__u16*)mydata->fatbuf)[off16]); - val1 &= 0xf000; - val2 = FAT2CPU16(((__u16*)mydata->fatbuf)[off16+1]); - val2 &= 0x00ff; - ret = (val2 << 4) | (val1 >> 12); - break; - case 2: - val1 = FAT2CPU16(((__u16*)mydata->fatbuf)[off16]); - val1 &= 0xff00; - val2 = FAT2CPU16(((__u16*)mydata->fatbuf)[off16+1]); - val2 &= 0x000f; - ret = (val2 << 8) | (val1 >> 8); - break; - case 3: - ret = FAT2CPU16(((__u16*)mydata->fatbuf)[off16]);; - ret = (ret & 0xfff0) >> 4; - break; - default: - break; - } - } - break; - } - FAT_DPRINT("ret: %d, offset: %d\n", ret, offset); - - return ret; -} - - -/* - * Read at most 'size' bytes from the specified cluster into 'buffer'. - * Return 0 on success, -1 otherwise. - */ -static int -get_cluster(fsdata *mydata, __u32 clustnum, __u8 *buffer, unsigned long size) -{ - int idx = 0; - __u32 startsect; - - if (clustnum > 0) { - startsect = mydata->data_begin + clustnum*mydata->clust_size; - } else { - startsect = mydata->rootdir_sect; - } - - FAT_DPRINT("gc - clustnum: %d, startsect: %d\n", clustnum, startsect); - if (disk_read(startsect, size/FS_BLOCK_SIZE , buffer) < 0) { - FAT_DPRINT("Error reading data\n"); - return -1; - } - if(size % FS_BLOCK_SIZE) { - __u8 tmpbuf[FS_BLOCK_SIZE]; - idx= size/FS_BLOCK_SIZE; - if (disk_read(startsect + idx, 1, tmpbuf) < 0) { - FAT_DPRINT("Error reading data\n"); - return -1; - } - buffer += idx*FS_BLOCK_SIZE; - - memcpy(buffer, tmpbuf, size % FS_BLOCK_SIZE); - return 0; - } - - return 0; -} - - -/* - * Read at most 'maxsize' bytes from the file associated with 'dentptr' - * into 'buffer'. - * Return the number of bytes read or -1 on fatal errors. - */ -static long -get_contents(fsdata *mydata, dir_entry *dentptr, __u8 *buffer, - unsigned long maxsize) -{ - unsigned long filesize = FAT2CPU32(dentptr->size), gotsize = 0; - unsigned int bytesperclust = mydata->clust_size * SECTOR_SIZE; - __u32 curclust = START(dentptr); - __u32 endclust, newclust; - unsigned long actsize; - - FAT_DPRINT("Filesize: %ld bytes\n", filesize); - - if (maxsize > 0 && filesize > maxsize) filesize = maxsize; - - FAT_DPRINT("Reading: %ld bytes\n", filesize); - - actsize=bytesperclust; - endclust=curclust; - do { - /* search for consecutive clusters */ - while(actsize < filesize) { - newclust = get_fatent(mydata, endclust); - if((newclust -1)!=endclust) - goto getit; - if (newclust <= 0x0001 || newclust >= 0xfff0) { - FAT_DPRINT("curclust: 0x%x\n", newclust); - FAT_DPRINT("Invalid FAT entry\n"); - return gotsize; - } - endclust=newclust; - actsize+= bytesperclust; - } - /* actsize >= file size */ - actsize -= bytesperclust; - /* get remaining clusters */ - if (get_cluster(mydata, curclust, buffer, (int)actsize) != 0) { - FAT_ERROR("Error reading cluster\n"); - return -1; - } - /* get remaining bytes */ - gotsize += (int)actsize; - filesize -= actsize; - buffer += actsize; - actsize= filesize; - if (get_cluster(mydata, endclust, buffer, (int)actsize) != 0) { - FAT_ERROR("Error reading cluster\n"); - return -1; - } - gotsize+=actsize; - return gotsize; -getit: - if (get_cluster(mydata, curclust, buffer, (int)actsize) != 0) { - FAT_ERROR("Error reading cluster\n"); - return -1; - } - gotsize += (int)actsize; - filesize -= actsize; - buffer += actsize; - curclust = get_fatent(mydata, endclust); - if (curclust <= 0x0001 || curclust >= 0xfff0) { - FAT_DPRINT("curclust: 0x%x\n", curclust); - FAT_ERROR("Invalid FAT entry\n"); - return gotsize; - } - actsize=bytesperclust; - endclust=curclust; - } while (1); -} - - -#ifdef CONFIG_SUPPORT_VFAT -/* - * Extract the file name information from 'slotptr' into 'l_name', - * starting at l_name[*idx]. - * Return 1 if terminator (zero byte) is found, 0 otherwise. - */ -static int -slot2str(dir_slot *slotptr, char *l_name, int *idx) -{ - int j; - - for (j = 0; j <= 8; j += 2) { - l_name[*idx] = slotptr->name0_4[j]; - if (l_name[*idx] == 0x00) return 1; - (*idx)++; - } - for (j = 0; j <= 10; j += 2) { - l_name[*idx] = slotptr->name5_10[j]; - if (l_name[*idx] == 0x00) return 1; - (*idx)++; - } - for (j = 0; j <= 2; j += 2) { - l_name[*idx] = slotptr->name11_12[j]; - if (l_name[*idx] == 0x00) return 1; - (*idx)++; - } - - return 0; -} - - -/* - * Extract the full long filename starting at 'retdent' (which is really - * a slot) into 'l_name'. If successful also copy the real directory entry - * into 'retdent' - * Return 0 on success, -1 otherwise. - */ -__u8 get_vfatname_block[MAX_CLUSTSIZE]; -static int -get_vfatname(fsdata *mydata, int curclust, __u8 *cluster, - dir_entry *retdent, char *l_name) -{ - dir_entry *realdent; - dir_slot *slotptr = (dir_slot*) retdent; - __u8 *nextclust = cluster + mydata->clust_size * SECTOR_SIZE; - __u8 counter = (slotptr->id & ~LAST_LONG_ENTRY_MASK) & 0xff; - int idx = 0; - - while ((__u8*)slotptr < nextclust) { - if (counter == 0) break; - if (((slotptr->id & ~LAST_LONG_ENTRY_MASK) & 0xff) != counter) - return -1; - slotptr++; - counter--; - } - - if ((__u8*)slotptr >= nextclust) { - dir_slot *slotptr2; - - slotptr--; - curclust = get_fatent(mydata, curclust); - if (curclust <= 0x0001 || curclust >= 0xfff0) { - FAT_DPRINT("curclust: 0x%x\n", curclust); - FAT_ERROR("Invalid FAT entry\n"); - return -1; - } - if (get_cluster(mydata, curclust, get_vfatname_block, - mydata->clust_size * SECTOR_SIZE) != 0) { - FAT_DPRINT("Error: reading directory block\n"); - return -1; - } - slotptr2 = (dir_slot*) get_vfatname_block; - while (slotptr2->id > 0x01) { - slotptr2++; - } - /* Save the real directory entry */ - realdent = (dir_entry*)slotptr2 + 1; - while ((__u8*)slotptr2 >= get_vfatname_block) { - slot2str(slotptr2, l_name, &idx); - slotptr2--; - } - } else { - /* Save the real directory entry */ - realdent = (dir_entry*)slotptr; - } - - do { - slotptr--; - if (slot2str(slotptr, l_name, &idx)) break; - } while (!(slotptr->id & LAST_LONG_ENTRY_MASK)); - - l_name[idx] = '\0'; - if (*l_name == DELETED_FLAG) *l_name = '\0'; - else if (*l_name == aRING) *l_name = 'å'; - downcase(l_name); - - /* Return the real directory entry */ - memcpy(retdent, realdent, sizeof(dir_entry)); - - return 0; -} - - -/* Calculate short name checksum */ -static __u8 -mkcksum(const char *str) -{ - int i; - __u8 ret = 0; - - for (i = 0; i < 11; i++) { - ret = (((ret&1)<<7)|((ret&0xfe)>>1)) + str[i]; - } - - return ret; -} -#endif - - -/* - * Get the directory entry associated with 'filename' from the directory - * starting at 'startsect' - */ -__u8 get_dentfromdir_block[MAX_CLUSTSIZE]; -static dir_entry *get_dentfromdir (fsdata * mydata, int startsect, - char *filename, dir_entry * retdent, - int dols) -{ - __u16 prevcksum = 0xffff; - __u32 curclust = START (retdent); - int files = 0, dirs = 0; - - FAT_DPRINT ("get_dentfromdir: %s\n", filename); - while (1) { - dir_entry *dentptr; - int i; - - if (get_cluster (mydata, curclust, get_dentfromdir_block, - mydata->clust_size * SECTOR_SIZE) != 0) { - FAT_DPRINT ("Error: reading directory block\n"); - return NULL; - } - dentptr = (dir_entry *) get_dentfromdir_block; - for (i = 0; i < DIRENTSPERCLUST; i++) { - char s_name[14], l_name[256]; - - l_name[0] = '\0'; - if (dentptr->name[0] == DELETED_FLAG) { - dentptr++; - continue; - } - if ((dentptr->attr & ATTR_VOLUME)) { -#ifdef CONFIG_SUPPORT_VFAT - if ((dentptr->attr & ATTR_VFAT) && - (dentptr->name[0] & LAST_LONG_ENTRY_MASK)) { - prevcksum = ((dir_slot *) dentptr) - ->alias_checksum; - get_vfatname (mydata, curclust, get_dentfromdir_block, - dentptr, l_name); - if (dols) { - int isdir = (dentptr->attr & ATTR_DIR); - char dirc; - int doit = 0; - - if (isdir) { - dirs++; - dirc = '/'; - doit = 1; - } else { - dirc = ' '; - if (l_name[0] != 0) { - files++; - doit = 1; - } - } - if (doit) { - if (dirc == ' ') { - printf (" %8ld %s%c\n", - (long) FAT2CPU32 (dentptr->size), - l_name, dirc); - } else { - printf (" %s%c\n", l_name, dirc); - } - } - dentptr++; - continue; - } - FAT_DPRINT ("vfatname: |%s|\n", l_name); - } else -#endif - { - /* Volume label or VFAT entry */ - dentptr++; - continue; - } - } - if (dentptr->name[0] == 0) { - if (dols) { - printf ("\n%d file(s), %d dir(s)\n\n", files, dirs); - } - FAT_DPRINT ("Dentname == NULL - %d\n", i); - return NULL; - } -#ifdef CONFIG_SUPPORT_VFAT - if (dols && mkcksum (dentptr->name) == prevcksum) { - dentptr++; - continue; - } -#endif - get_name (dentptr, s_name); - if (dols) { - int isdir = (dentptr->attr & ATTR_DIR); - char dirc; - int doit = 0; - - if (isdir) { - dirs++; - dirc = '/'; - doit = 1; - } else { - dirc = ' '; - if (s_name[0] != 0) { - files++; - doit = 1; - } - } - if (doit) { - if (dirc == ' ') { - printf (" %8ld %s%c\n", - (long) FAT2CPU32 (dentptr->size), s_name, - dirc); - } else { - printf (" %s%c\n", s_name, dirc); - } - } - dentptr++; - continue; - } - if (strcmp (filename, s_name) && strcmp (filename, l_name)) { - FAT_DPRINT ("Mismatch: |%s|%s|\n", s_name, l_name); - dentptr++; - continue; - } - memcpy (retdent, dentptr, sizeof (dir_entry)); - - FAT_DPRINT ("DentName: %s", s_name); - FAT_DPRINT (", start: 0x%x", START (dentptr)); - FAT_DPRINT (", size: 0x%x %s\n", - FAT2CPU32 (dentptr->size), - (dentptr->attr & ATTR_DIR) ? "(DIR)" : ""); - - return retdent; - } - curclust = get_fatent (mydata, curclust); - if (curclust <= 0x0001 || curclust >= 0xfff0) { - FAT_DPRINT ("curclust: 0x%x\n", curclust); - FAT_ERROR ("Invalid FAT entry\n"); - return NULL; - } - } - - return NULL; -} - - -/* - * Read boot sector and volume info from a FAT filesystem - */ -static int -read_bootsectandvi(boot_sector *bs, volume_info *volinfo, int *fatsize) -{ - __u8 block[FS_BLOCK_SIZE]; - volume_info *vistart; - - if (disk_read(0, 1, block) < 0) { - FAT_DPRINT("Error: reading block\n"); - return -1; - } - - memcpy(bs, block, sizeof(boot_sector)); - bs->reserved = FAT2CPU16(bs->reserved); - bs->fat_length = FAT2CPU16(bs->fat_length); - bs->secs_track = FAT2CPU16(bs->secs_track); - bs->heads = FAT2CPU16(bs->heads); - bs->total_sect = FAT2CPU32(bs->total_sect); - - /* FAT32 entries */ - if (bs->fat_length == 0) { - /* Assume FAT32 */ - bs->fat32_length = FAT2CPU32(bs->fat32_length); - bs->flags = FAT2CPU16(bs->flags); - bs->root_cluster = FAT2CPU32(bs->root_cluster); - bs->info_sector = FAT2CPU16(bs->info_sector); - bs->backup_boot = FAT2CPU16(bs->backup_boot); - vistart = (volume_info*) (block + sizeof(boot_sector)); - *fatsize = 32; - } else { - vistart = (volume_info*) &(bs->fat32_length); - *fatsize = 0; - } - memcpy(volinfo, vistart, sizeof(volume_info)); - - /* Terminate fs_type string. Writing past the end of vistart - is ok - it's just the buffer. */ - vistart->fs_type[8] = '\0'; - - if (*fatsize == 32) { - if (compare_sign(FAT32_SIGN, vistart->fs_type) == 0) { - return 0; - } - } else { - if (compare_sign(FAT12_SIGN, vistart->fs_type) == 0) { - *fatsize = 12; - return 0; - } - if (compare_sign(FAT16_SIGN, vistart->fs_type) == 0) { - *fatsize = 16; - return 0; - } - } - - FAT_DPRINT("Error: broken fs_type sign\n"); - return -1; -} - - -__u8 do_fat_read_block[MAX_CLUSTSIZE]; /* Block buffer */ -long -do_fat_read (const char *filename, void *buffer, unsigned long maxsize, - int dols) -{ -#if CONFIG_NIOS /* NIOS CPU cannot access big automatic arrays */ - static -#endif - char fnamecopy[2048]; - boot_sector bs; - volume_info volinfo; - fsdata datablock; - fsdata *mydata = &datablock; - dir_entry *dentptr; - __u16 prevcksum = 0xffff; - char *subname = ""; - int rootdir_size, cursect; - int idx, isdir = 0; - int files = 0, dirs = 0; - long ret = 0; - int firsttime; - - if (read_bootsectandvi (&bs, &volinfo, &mydata->fatsize)) { - FAT_DPRINT ("Error: reading boot sector\n"); - return -1; - } - if (mydata->fatsize == 32) { - mydata->fatlength = bs.fat32_length; - } else { - mydata->fatlength = bs.fat_length; - } - mydata->fat_sect = bs.reserved; - cursect = mydata->rootdir_sect - = mydata->fat_sect + mydata->fatlength * bs.fats; - mydata->clust_size = bs.cluster_size; - if (mydata->fatsize == 32) { - rootdir_size = mydata->clust_size; - mydata->data_begin = mydata->rootdir_sect /* + rootdir_size */ - - (mydata->clust_size * 2); - } else { - rootdir_size = ((bs.dir_entries[1] * (int) 256 + bs.dir_entries[0]) - * sizeof (dir_entry)) / SECTOR_SIZE; - mydata->data_begin = mydata->rootdir_sect + rootdir_size - - (mydata->clust_size * 2); - } - mydata->fatbufnum = -1; - - FAT_DPRINT ("FAT%d, fatlength: %d\n", mydata->fatsize, - mydata->fatlength); - FAT_DPRINT ("Rootdir begins at sector: %d, offset: %x, size: %d\n" - "Data begins at: %d\n", - mydata->rootdir_sect, mydata->rootdir_sect * SECTOR_SIZE, - rootdir_size, mydata->data_begin); - FAT_DPRINT ("Cluster size: %d\n", mydata->clust_size); - - /* "cwd" is always the root... */ - while (ISDIRDELIM (*filename)) - filename++; - /* Make a copy of the filename and convert it to lowercase */ - strcpy (fnamecopy, filename); - downcase (fnamecopy); - if (*fnamecopy == '\0') { - if (!dols) - return -1; - dols = LS_ROOT; - } else if ((idx = dirdelim (fnamecopy)) >= 0) { - isdir = 1; - fnamecopy[idx] = '\0'; - subname = fnamecopy + idx + 1; - /* Handle multiple delimiters */ - while (ISDIRDELIM (*subname)) - subname++; - } else if (dols) { - isdir = 1; - } - - while (1) { - int i; - - if (disk_read (cursect, mydata->clust_size, do_fat_read_block) < 0) { - FAT_DPRINT ("Error: reading rootdir block\n"); - return -1; - } - dentptr = (dir_entry *) do_fat_read_block; - for (i = 0; i < DIRENTSPERBLOCK; i++) { - char s_name[14], l_name[256]; - - l_name[0] = '\0'; - if ((dentptr->attr & ATTR_VOLUME)) { -#ifdef CONFIG_SUPPORT_VFAT - if ((dentptr->attr & ATTR_VFAT) && - (dentptr->name[0] & LAST_LONG_ENTRY_MASK)) { - prevcksum = ((dir_slot *) dentptr)->alias_checksum; - get_vfatname (mydata, 0, do_fat_read_block, dentptr, l_name); - if (dols == LS_ROOT) { - int isdir = (dentptr->attr & ATTR_DIR); - char dirc; - int doit = 0; - - if (isdir) { - dirs++; - dirc = '/'; - doit = 1; - } else { - dirc = ' '; - if (l_name[0] != 0) { - files++; - doit = 1; - } - } - if (doit) { - if (dirc == ' ') { - printf (" %8ld %s%c\n", - (long) FAT2CPU32 (dentptr->size), - l_name, dirc); - } else { - printf (" %s%c\n", l_name, dirc); - } - } - dentptr++; - continue; - } - FAT_DPRINT ("Rootvfatname: |%s|\n", l_name); - } else -#endif - { - /* Volume label or VFAT entry */ - dentptr++; - continue; - } - } else if (dentptr->name[0] == 0) { - FAT_DPRINT ("RootDentname == NULL - %d\n", i); - if (dols == LS_ROOT) { - printf ("\n%d file(s), %d dir(s)\n\n", files, dirs); - return 0; - } - return -1; - } -#ifdef CONFIG_SUPPORT_VFAT - else if (dols == LS_ROOT - && mkcksum (dentptr->name) == prevcksum) { - dentptr++; - continue; - } -#endif - get_name (dentptr, s_name); - if (dols == LS_ROOT) { - int isdir = (dentptr->attr & ATTR_DIR); - char dirc; - int doit = 0; - - if (isdir) { - dirc = '/'; - if (s_name[0] != 0) { - dirs++; - doit = 1; - } - } else { - dirc = ' '; - if (s_name[0] != 0) { - files++; - doit = 1; - } - } - if (doit) { - if (dirc == ' ') { - printf (" %8ld %s%c\n", - (long) FAT2CPU32 (dentptr->size), s_name, - dirc); - } else { - printf (" %s%c\n", s_name, dirc); - } - } - dentptr++; - continue; - } - if (strcmp (fnamecopy, s_name) && strcmp (fnamecopy, l_name)) { - FAT_DPRINT ("RootMismatch: |%s|%s|\n", s_name, l_name); - dentptr++; - continue; - } - if (isdir && !(dentptr->attr & ATTR_DIR)) - return -1; - - FAT_DPRINT ("RootName: %s", s_name); - FAT_DPRINT (", start: 0x%x", START (dentptr)); - FAT_DPRINT (", size: 0x%x %s\n", - FAT2CPU32 (dentptr->size), isdir ? "(DIR)" : ""); - - goto rootdir_done; /* We got a match */ - } - cursect++; - } - rootdir_done: - - firsttime = 1; - while (isdir) { - int startsect = mydata->data_begin - + START (dentptr) * mydata->clust_size; - dir_entry dent; - char *nextname = NULL; - - dent = *dentptr; - dentptr = &dent; - - idx = dirdelim (subname); - if (idx >= 0) { - subname[idx] = '\0'; - nextname = subname + idx + 1; - /* Handle multiple delimiters */ - while (ISDIRDELIM (*nextname)) - nextname++; - if (dols && *nextname == '\0') - firsttime = 0; - } else { - if (dols && firsttime) { - firsttime = 0; - } else { - isdir = 0; - } - } - - if (get_dentfromdir (mydata, startsect, subname, dentptr, - isdir ? 0 : dols) == NULL) { - if (dols && !isdir) - return 0; - return -1; - } - - if (idx >= 0) { - if (!(dentptr->attr & ATTR_DIR)) - return -1; - subname = nextname; - } - } - ret = get_contents (mydata, dentptr, buffer, maxsize); - FAT_DPRINT ("Size: %d, got: %ld\n", FAT2CPU32 (dentptr->size), ret); - - return ret; -} - - -int -file_fat_detectfs(void) -{ - boot_sector bs; - volume_info volinfo; - int fatsize; - char vol_label[12]; - - if(cur_dev==NULL) { - printf("No current device\n"); - return 1; - } -#if (CONFIG_COMMANDS & CFG_CMD_IDE) || (CONFIG_COMMANDS & CFG_CMD_SCSI) || \ - (CONFIG_COMMANDS & CFG_CMD_USB) || (CONFIG_MMC) - printf("Interface: "); - switch(cur_dev->if_type) { - case IF_TYPE_IDE : printf("IDE"); break; - case IF_TYPE_SCSI : printf("SCSI"); break; - case IF_TYPE_ATAPI : printf("ATAPI"); break; - case IF_TYPE_USB : printf("USB"); break; - case IF_TYPE_DOC : printf("DOC"); break; - case IF_TYPE_MMC : printf("MMC"); break; - default : printf("Unknown"); - } - printf("\n Device %d: ",cur_dev->dev); - dev_print(cur_dev); -#endif - if(read_bootsectandvi(&bs, &volinfo, &fatsize)) { - printf("\nNo valid FAT fs found\n"); - return 1; - } - memcpy (vol_label, volinfo.volume_label, 11); - vol_label[11] = '\0'; - volinfo.fs_type[5]='\0'; - printf("Partition %d: Filesystem: %s \"%s\"\n",cur_part,volinfo.fs_type,vol_label); - return 0; -} - - -int -file_fat_ls(const char *dir) -{ - return do_fat_read(dir, NULL, 0, LS_YES); -} - - -long -file_fat_read(const char *filename, void *buffer, unsigned long maxsize) -{ - printf("reading %s\n",filename); - return do_fat_read(filename, buffer, maxsize, LS_NO); -} - -#endif /* #if (CONFIG_COMMANDS & CFG_CMD_FAT) */ diff --git a/fs/fat/file.c b/fs/fat/file.c deleted file mode 100644 index f999ac5a25..0000000000 --- a/fs/fat/file.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - * file.c - * - * Mini "VFS" by Marcus Sundberg - * - * 2002-07-28 - rjones@nexus-tech.net - ported to ppcboot v1.1.6 - * 2003-03-10 - kharris@nexus-tech.net - ported to uboot - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> -#include <config.h> -#include <malloc.h> -#include <fat.h> -#include <linux/stat.h> -#include <linux/time.h> - -#if (CONFIG_COMMANDS & CFG_CMD_FAT) - -/* Supported filesystems */ -static const struct filesystem filesystems[] = { - { file_fat_detectfs, file_fat_ls, file_fat_read, "FAT" }, -}; -#define NUM_FILESYS (sizeof(filesystems)/sizeof(struct filesystem)) - -/* The filesystem which was last detected */ -static int current_filesystem = FSTYPE_NONE; - -/* The current working directory */ -#define CWD_LEN 511 -char file_cwd[CWD_LEN+1] = "/"; - -const char * -file_getfsname(int idx) -{ - if (idx < 0 || idx >= NUM_FILESYS) return NULL; - - return filesystems[idx].name; -} - - -static void -pathcpy(char *dest, const char *src) -{ - char *origdest = dest; - - do { - if (dest-file_cwd >= CWD_LEN) { - *dest = '\0'; - return; - } - *(dest) = *(src); - if (*src == '\0') { - if (dest-- != origdest && ISDIRDELIM(*dest)) { - *dest = '\0'; - } - return; - } - ++dest; - if (ISDIRDELIM(*src)) { - while (ISDIRDELIM(*src)) src++; - } else { - src++; - } - } while (1); -} - - -int -file_cd(const char *path) -{ - if (ISDIRDELIM(*path)) { - while (ISDIRDELIM(*path)) path++; - strncpy(file_cwd+1, path, CWD_LEN-1); - } else { - const char *origpath = path; - char *tmpstr = file_cwd; - int back = 0; - - while (*tmpstr != '\0') tmpstr++; - do { - tmpstr--; - } while (ISDIRDELIM(*tmpstr)); - - while (*path == '.') { - path++; - while (*path == '.') { - path++; - back++; - } - if (*path != '\0' && !ISDIRDELIM(*path)) { - path = origpath; - back = 0; - break; - } - while (ISDIRDELIM(*path)) path++; - origpath = path; - } - - while (back--) { - /* Strip off path component */ - while (!ISDIRDELIM(*tmpstr)) { - tmpstr--; - } - if (tmpstr == file_cwd) { - /* Incremented again right after the loop. */ - tmpstr--; - break; - } - /* Skip delimiters */ - while (ISDIRDELIM(*tmpstr)) tmpstr--; - } - tmpstr++; - if (*path == '\0') { - if (tmpstr == file_cwd) { - *tmpstr = '/'; - tmpstr++; - } - *tmpstr = '\0'; - return 0; - } - *tmpstr = '/'; - pathcpy(tmpstr+1, path); - } - - return 0; -} - - -int -file_detectfs(void) -{ - int i; - - current_filesystem = FSTYPE_NONE; - - for (i = 0; i < NUM_FILESYS; i++) { - if (filesystems[i].detect() == 0) { - strcpy(file_cwd, "/"); - current_filesystem = i; - break; - } - } - - return current_filesystem; -} - - -int -file_ls(const char *dir) -{ - char fullpath[1024]; - const char *arg; - - if (current_filesystem == FSTYPE_NONE) { - printf("Can't list files without a filesystem!\n"); - return -1; - } - - if (ISDIRDELIM(*dir)) { - arg = dir; - } else { - sprintf(fullpath, "%s/%s", file_cwd, dir); - arg = fullpath; - } - return filesystems[current_filesystem].ls(arg); -} - - -long -file_read(const char *filename, void *buffer, unsigned long maxsize) -{ - char fullpath[1024]; - const char *arg; - - if (current_filesystem == FSTYPE_NONE) { - printf("Can't load file without a filesystem!\n"); - return -1; - } - - if (ISDIRDELIM(*filename)) { - arg = filename; - } else { - sprintf(fullpath, "%s/%s", file_cwd, filename); - arg = fullpath; - } - - return filesystems[current_filesystem].read(arg, buffer, maxsize); -} - -#endif /* #if (CONFIG_COMMANDS & CFG_CMD_FAT) */ diff --git a/fs/fdos/Makefile b/fs/fdos/Makefile deleted file mode 100644 index 2dba0fb690..0000000000 --- a/fs/fdos/Makefile +++ /dev/null @@ -1,54 +0,0 @@ -# -# (C) Copyright 2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# (C) Copyright 2002 -# Stäubli Faverges - <www.staubli.com> -# Pierre AUBERT p.aubert@staubli.com -# -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)libfdos.a - -AOBJS = -COBJS = fat.o vfat.o dev.o fdos.o fs.o subdir.o - -SRCS := $(AOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(AOBJS) $(COBJS)) - -#CPPFLAGS += - -all: $(LIB) $(AOBJS) - -$(LIB): $(obj).depend $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/fs/fdos/dev.c b/fs/fdos/dev.c deleted file mode 100644 index 5dea5cd788..0000000000 --- a/fs/fdos/dev.c +++ /dev/null @@ -1,195 +0,0 @@ -/* - * (C) Copyright 2002 - * Stäubli Faverges - <www.staubli.com> - * Pierre AUBERT p.aubert@staubli.com - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> -#include <config.h> - -#include "dos.h" -#include "fdos.h" - -#if (CONFIG_COMMANDS & CFG_CMD_FDOS) - -#define NB_HEADS 2 -#define NB_TRACKS 80 -#define NB_SECTORS 18 - - -static int lastwhere; - -/*----------------------------------------------------------------------------- - * dev_open -- - *----------------------------------------------------------------------------- - */ -int dev_open (void) -{ - lastwhere = 0; - return (0); -} - -/*----------------------------------------------------------------------------- - * dev_read -- len and where are sectors number - *----------------------------------------------------------------------------- - */ -int dev_read (void *buffer, int where, int len) -{ - PRINTF ("dev_read (len = %d, where = %d)\n", len, where); - - /* Si on ne desire pas lire a la position courante, il faut un seek */ - if (where != lastwhere) { - if (!fdc_fdos_seek (where)) { - PRINTF ("seek error in dev_read"); - lastwhere = -1; - return (-1); - } - } - - if (!fdc_fdos_read (buffer, len)) { - PRINTF ("read error\n"); - lastwhere = -1; - return (-1); - } - lastwhere = where + len; - return (0); -} -/*----------------------------------------------------------------------------- - * check_dev -- verify the diskette format - *----------------------------------------------------------------------------- - */ -int check_dev (BootSector_t *boot, Fs_t *fs) -{ - unsigned int heads, sectors, tracks; - int BootP, Infp0, InfpX, InfTm; - int sect_per_track; - - /* Display Boot header */ - PRINTF ("Jump to boot code 0x%02x 0x%02x 0x%02x\n", - boot -> jump [0], boot -> jump [1], boot -> jump[2]); - PRINTF ("OEM name & version '%*.*s'\n", - BANNER_LG, BANNER_LG, boot -> banner ); - PRINTF ("Bytes per sector hopefully 512 %d\n", - __le16_to_cpu (boot -> secsiz)); - PRINTF ("Cluster size in sectors %d\n", - boot -> clsiz); - PRINTF ("Number of reserved (boot) sectors %d\n", - __le16_to_cpu (boot -> nrsvsect)); - PRINTF ("Number of FAT tables hopefully 2 %d\n", - boot -> nfat); - PRINTF ("Number of directory slots %d\n", - __le16_to_cpu (boot -> dirents)); - PRINTF ("Total sectors on disk %d\n", - __le16_to_cpu (boot -> psect)); - PRINTF ("Media descriptor=first byte of FAT %d\n", - boot -> descr); - PRINTF ("Sectors in FAT %d\n", - __le16_to_cpu (boot -> fatlen)); - PRINTF ("Sectors/track %d\n", - __le16_to_cpu (boot -> nsect)); - PRINTF ("Heads %d\n", - __le16_to_cpu (boot -> nheads)); - PRINTF ("number of hidden sectors %d\n", - __le32_to_cpu (boot -> nhs)); - PRINTF ("big total sectors %d\n", - __le32_to_cpu (boot -> bigsect)); - PRINTF ("physical drive ? %d\n", - boot -> physdrive); - PRINTF ("reserved %d\n", - boot -> reserved); - PRINTF ("dos > 4.0 diskette %d\n", - boot -> dos4); - PRINTF ("serial number %d\n", - __le32_to_cpu (boot -> serial)); - PRINTF ("disk label %*.*s\n", - LABEL_LG, LABEL_LG, boot -> label); - PRINTF ("FAT type %8.8s\n", - boot -> fat_type); - PRINTF ("reserved by 2M %d\n", - boot -> res_2m); - PRINTF ("2M checksum (not used) %d\n", - boot -> CheckSum); - PRINTF ("2MF format version %d\n", - boot -> fmt_2mf); - PRINTF ("1 if write track after format %d\n", - boot -> wt); - PRINTF ("data transfer rate on track 0 %d\n", - boot -> rate_0); - PRINTF ("data transfer rate on track<>0 %d\n", - boot -> rate_any); - PRINTF ("offset to boot program %d\n", - __le16_to_cpu (boot -> BootP)); - PRINTF ("T1: information for track 0 %d\n", - __le16_to_cpu (boot -> Infp0)); - PRINTF ("T2: information for track<>0 %d\n", - __le16_to_cpu (boot -> InfpX)); - PRINTF ("T3: track sectors size table %d\n", - __le16_to_cpu (boot -> InfTm)); - PRINTF ("Format date 0x%04x\n", - __le16_to_cpu (boot -> DateF)); - PRINTF ("Format time 0x%04x\n", - __le16_to_cpu (boot -> TimeF)); - - - /* information is extracted from boot sector */ - heads = __le16_to_cpu (boot -> nheads); - sectors = __le16_to_cpu (boot -> nsect); - fs -> tot_sectors = __le32_to_cpu (boot -> bigsect); - if (__le16_to_cpu (boot -> psect) != 0) { - fs -> tot_sectors = __le16_to_cpu (boot -> psect); - } - - sect_per_track = heads * sectors; - tracks = (fs -> tot_sectors + sect_per_track - 1) / sect_per_track; - - BootP = __le16_to_cpu (boot -> BootP); - Infp0 = __le16_to_cpu (boot -> Infp0); - InfpX = __le16_to_cpu (boot -> InfpX); - InfTm = __le16_to_cpu (boot -> InfTm); - - if (boot -> dos4 == EXTENDED_BOOT && - strncmp( boot->banner,"2M", 2 ) == 0 && - BootP < SZ_STD_SECTOR && - Infp0 < SZ_STD_SECTOR && - InfpX < SZ_STD_SECTOR && - InfTm < SZ_STD_SECTOR && - BootP >= InfTm + 2 && - InfTm >= InfpX && - InfpX >= Infp0 && - Infp0 >= 76 ) { - - return (-1); - } - - if (heads != NB_HEADS || - tracks != NB_TRACKS || - sectors != NB_SECTORS || - __le16_to_cpu (boot -> secsiz) != SZ_STD_SECTOR || - fs -> tot_sectors == 0 || - (fs -> tot_sectors % sectors) != 0) { - return (-1); - } - - return (0); -} - - -#endif diff --git a/fs/fdos/dos.h b/fs/fdos/dos.h deleted file mode 100644 index 7b27b01e02..0000000000 --- a/fs/fdos/dos.h +++ /dev/null @@ -1,175 +0,0 @@ -/* - * (C) Copyright 2002 - * Stäubli Faverges - <www.staubli.com> - * Pierre AUBERT p.aubert@staubli.com - * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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 _DOS_H_ -#define _DOS_H_ - -/* Definitions for Dos diskettes */ - -/* General definitions */ -#define SZ_STD_SECTOR 512 /* Standard sector size */ -#define MDIR_SIZE 32 /* Direntry size */ -#define FAT_BITS 12 /* Diskette use 12 bits fat */ - -#define MAX_PATH 128 /* Max size of the MSDOS PATH */ -#define MAX_DIR_SECS 64 /* Taille max d'un repertoire (en */ - /* secteurs) */ -/* Misc. definitions */ -#define DELMARK '\xe5' -#define EXTENDED_BOOT (0x29) -#define MEDIA_STD (0xf0) -#define JUMP_0_1 (0xe9) -#define JUMP_0_2 (0xeb) - -/* Boot size is 256 bytes, but we need to read almost a sector, then - assume bootsize is 512 */ -#define BOOTSIZE 512 - -/* Fat definitions for 12 bits fat */ -#define FAT12_MAX_NB 4086 -#define FAT12_LAST 0x0ff6 -#define FAT12_END 0x0fff - -/* file attributes */ -#define ATTR_READONLY 0x01 -#define ATTR_HIDDEN 0x02 -#define ATTR_SYSTEM 0x04 -#define ATTR_VOLUME 0x08 -#define ATTR_DIRECTORY 0x10 -#define ATTR_ARCHIVE 0x20 -#define ATTR_VSE 0x0f - -/* Name format */ -#define EXTCASE 0x10 -#define BASECASE 0x8 - -/* Definition of the boot sector */ -#define BANNER_LG 8 -#define LABEL_LG 11 - -typedef struct bootsector -{ - unsigned char jump [3]; /* 0 Jump to boot code */ - char banner [BANNER_LG]; /* 3 OEM name & version */ - unsigned short secsiz; /* 11 Bytes per sector hopefully 512 */ - unsigned char clsiz; /* 13 Cluster size in sectors */ - unsigned short nrsvsect; /* 14 Number of reserved (boot) sectors */ - unsigned char nfat; /* 16 Number of FAT tables hopefully 2 */ - unsigned short dirents; /* 17 Number of directory slots */ - unsigned short psect; /* 19 Total sectors on disk */ - unsigned char descr; /* 21 Media descriptor=first byte of FAT */ - unsigned short fatlen; /* 22 Sectors in FAT */ - unsigned short nsect; /* 24 Sectors/track */ - unsigned short nheads; /* 26 Heads */ - unsigned int nhs; /* 28 number of hidden sectors */ - unsigned int bigsect; /* 32 big total sectors */ - unsigned char physdrive; /* 36 physical drive ? */ - unsigned char reserved; /* 37 reserved */ - unsigned char dos4; /* 38 dos > 4.0 diskette */ - unsigned int serial; /* 39 serial number */ - char label [LABEL_LG]; /* 43 disk label */ - char fat_type [8]; /* 54 FAT type */ - unsigned char res_2m; /* 62 reserved by 2M */ - unsigned char CheckSum; /* 63 2M checksum (not used) */ - unsigned char fmt_2mf; /* 64 2MF format version */ - unsigned char wt; /* 65 1 if write track after format */ - unsigned char rate_0; /* 66 data transfer rate on track 0 */ - unsigned char rate_any; /* 67 data transfer rate on track<>0 */ - unsigned short BootP; /* 68 offset to boot program */ - unsigned short Infp0; /* 70 T1: information for track 0 */ - unsigned short InfpX; /* 72 T2: information for track<>0 */ - unsigned short InfTm; /* 74 T3: track sectors size table */ - unsigned short DateF; /* 76 Format date */ - unsigned short TimeF; /* 78 Format time */ - unsigned char junk [BOOTSIZE - 80]; /* 80 remaining data */ -} __attribute__ ((packed)) BootSector_t; - -/* Structure d'une entree de repertoire */ -typedef struct directory { - char name [8]; /* file name */ - char ext [3]; /* file extension */ - unsigned char attr; /* attribute byte */ - unsigned char Case; /* case of short filename */ - unsigned char reserved [9]; /* ?? */ - unsigned char time [2]; /* time stamp */ - unsigned char date [2]; /* date stamp */ - unsigned short start; /* starting cluster number */ - unsigned int size; /* size of the file */ -} __attribute__ ((packed)) Directory_t; - - -#define MAX_VFAT_SUBENTRIES 20 -#define VSE_NAMELEN 13 - -#define VSE1SIZE 5 -#define VSE2SIZE 6 -#define VSE3SIZE 2 - -#define VBUFSIZE ((MAX_VFAT_SUBENTRIES * VSE_NAMELEN) + 1) - -#define MAX_VNAMELEN (255) - -#define VSE_PRESENT 0x01 -#define VSE_LAST 0x40 -#define VSE_MASK 0x1f - -/* Flag used by vfat_lookup */ -#define DO_OPEN 1 -#define ACCEPT_PLAIN 0x20 -#define ACCEPT_DIR 0x10 -#define ACCEPT_LABEL 0x08 -#define SINGLE 2 -#define MATCH_ANY 0x40 - -struct vfat_subentry { - unsigned char id; /* VSE_LAST pour la fin, VSE_MASK */ - /* pour un VSE */ - char text1 [VSE1SIZE * 2]; /* Caracteres encodes sur 16 bits */ - unsigned char attribute; /* 0x0f pour les VFAT */ - unsigned char hash1; /* toujours 0 */ - unsigned char sum; /* Checksum du nom court */ - char text2 [VSE2SIZE * 2]; /* Caracteres encodes sur 16 bits */ - unsigned char sector_l; /* 0 pour les VFAT */ - unsigned char sector_u; /* 0 pour les VFAT */ - char text3 [VSE3SIZE * 2]; /* Caracteres encodes sur 16 bits */ -} __attribute__ ((packed)) ; - -struct vfat_state { - char name [VBUFSIZE]; - int status; /* is now a bit map of 32 bits */ - int subentries; - unsigned char sum; /* no need to remember the sum for each */ - /* entry, it is the same anyways */ -} __attribute__ ((packed)) ; - -/* Conversion macros */ -#define DOS_YEAR(dir) (((dir)->date[1] >> 1) + 1980) -#define DOS_MONTH(dir) (((((dir)->date[1]&0x1) << 3) + ((dir)->date[0] >> 5))) -#define DOS_DAY(dir) ((dir)->date[0] & 0x1f) -#define DOS_HOUR(dir) ((dir)->time[1] >> 3) -#define DOS_MINUTE(dir) (((((dir)->time[1]&0x7) << 3) + ((dir)->time[0] >> 5))) -#define DOS_SEC(dir) (((dir)->time[0] & 0x1f) * 2) - - -#endif diff --git a/fs/fdos/fat.c b/fs/fdos/fat.c deleted file mode 100644 index 2ef2371e17..0000000000 --- a/fs/fdos/fat.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * (C) Copyright 2002 - * Stäubli Faverges - <www.staubli.com> - * Pierre AUBERT p.aubert@staubli.com - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> -#include <config.h> -#include <malloc.h> - -#if (CONFIG_COMMANDS & CFG_CMD_FDOS) - -#include "dos.h" -#include "fdos.h" - - -/*----------------------------------------------------------------------------- - * fat_decode -- - *----------------------------------------------------------------------------- - */ -unsigned int fat_decode (Fs_t *fs, unsigned int num) -{ - unsigned int start = num * 3 / 2; - unsigned char *address = fs -> fat_buf + start; - - if (num < 2 || start + 1 > (fs -> fat_len * SZ_STD_SECTOR)) - return 1; - - if (num & 1) - return ((address [1] & 0xff) << 4) | ((address [0] & 0xf0 ) >> 4); - else - return ((address [1] & 0xf) << 8) | (address [0] & 0xff ); -} -/*----------------------------------------------------------------------------- - * check_fat -- - *----------------------------------------------------------------------------- - */ -static int check_fat (Fs_t *fs) -{ - int i, f; - - /* Cluster verification */ - for (i = 3 ; i < fs -> num_clus; i++){ - f = fat_decode (fs, i); - if (f < FAT12_LAST && f > fs -> num_clus){ - /* Wrong cluster number detected */ - return (-1); - } - } - return (0); -} -/*----------------------------------------------------------------------------- - * read_one_fat -- - *----------------------------------------------------------------------------- - */ -static int read_one_fat (BootSector_t *boot, Fs_t *fs, int nfat) -{ - if (dev_read (fs -> fat_buf, - (fs -> fat_start + nfat * fs -> fat_len), - fs -> fat_len) < 0) { - return (-1); - } - - if (fs -> fat_buf [0] || fs -> fat_buf [1] || fs -> fat_buf [2]) { - if ((fs -> fat_buf [0] != boot -> descr && - (fs -> fat_buf [0] != 0xf9 || boot -> descr != MEDIA_STD)) || - fs -> fat_buf [0] < MEDIA_STD){ - /* Unknown Media */ - return (-1); - } - if (fs -> fat_buf [1] != 0xff || fs -> fat_buf [2] != 0xff){ - /* FAT doesn't start with good values */ - return (-1); - } - } - - if (fs -> num_clus >= FAT12_MAX_NB) { - /* Too much clusters */ - return (-1); - } - - return check_fat (fs); -} -/*----------------------------------------------------------------------------- - * read_fat -- - *----------------------------------------------------------------------------- - */ -int read_fat (BootSector_t *boot, Fs_t *fs) -{ - unsigned int buflen; - int i; - - /* Allocate Fat Buffer */ - buflen = fs -> fat_len * SZ_STD_SECTOR; - if (fs -> fat_buf) { - free (fs -> fat_buf); - } - - if ((fs -> fat_buf = malloc (buflen)) == NULL) { - return (-1); - } - - /* Try to read each Fat */ - for (i = 0; i< fs -> nb_fat; i++){ - if (read_one_fat (boot, fs, i) == 0) { - /* Fat is OK */ - fs -> num_fat = i; - break; - } - } - - if (i == fs -> nb_fat){ - return (-1); - } - - if (fs -> fat_len > (((fs -> num_clus + 2) * - (FAT_BITS / 4) -1 ) / 2 / - SZ_STD_SECTOR + 1)) { - return (-1); - } - return (0); -} - -#endif diff --git a/fs/fdos/fdos.c b/fs/fdos/fdos.c deleted file mode 100644 index a29f43d978..0000000000 --- a/fs/fdos/fdos.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * (C) Copyright 2002 - * Stäubli Faverges - <www.staubli.com> - * Pierre AUBERT p.aubert@staubli.com - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> -#include <config.h> - -#if (CONFIG_COMMANDS & CFG_CMD_FDOS) -#include <malloc.h> -#include "dos.h" -#include "fdos.h" - - -const char *month [] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; - -Fs_t fs; -File_t file; - -/*----------------------------------------------------------------------------- - * dos_open -- - *----------------------------------------------------------------------------- - */ -int dos_open(char *name) -{ - int lg; - int entry; - char *fname; - - /* We need to suppress the " char around the name */ - if (name [0] == '"') { - name ++; - } - lg = strlen (name); - if (name [lg - 1] == '"') { - name [lg - 1] = '\0'; - } - - /* Open file system */ - if (fs_init (&fs) < 0) { - return -1; - } - - /* Init the file descriptor */ - file.name = name; - file.fs = &fs; - - /* find the subdirectory containing the file */ - if (open_subdir (&file) < 0) { - return (-1); - } - - fname = basename (name); - - /* if we try to open root directory */ - if (*fname == '\0') { - file.file = file.subdir; - return (0); - } - - /* find the file in the subdir */ - entry = 0; - if (vfat_lookup (&file.subdir, - file.fs, - &file.file.dir, - &entry, - 0, - fname, - ACCEPT_DIR | ACCEPT_PLAIN | SINGLE | DO_OPEN, - 0, - &file.file) != 0) { - /* File not found */ - printf ("File not found\n"); - return (-1); - } - - return 0; -} - -/*----------------------------------------------------------------------------- - * dos_read -- - *----------------------------------------------------------------------------- - */ -int dos_read (ulong addr) -{ - int read = 0, nb; - - /* Try to boot a directory ? */ - if (file.file.dir.attr & (ATTR_DIRECTORY | ATTR_VOLUME)) { - printf ("Unable to boot %s !!\n", file.name); - return (-1); - } - while (read < file.file.FileSize) { - PRINTF ("read_file (%ld)\n", (file.file.FileSize - read)); - nb = read_file (&fs, - &file.file, - (char *)addr + read, - read, - (file.file.FileSize - read)); - PRINTF ("read_file -> %d\n", nb); - if (nb < 0) { - printf ("read error\n"); - return (-1); - } - read += nb; - } - return (read); -} -/*----------------------------------------------------------------------------- - * dos_dir -- - *----------------------------------------------------------------------------- - */ -int dos_dir (void) -{ - int entry; - Directory_t dir; - char *name; - - - if ((file.file.dir.attr & ATTR_DIRECTORY) == 0) { - printf ("%s: not a directory !!\n", file.name); - return (1); - } - entry = 0; - if ((name = malloc (MAX_VNAMELEN + 1)) == NULL) { - PRINTF ("Allcation error\n"); - return (1); - } - - while (vfat_lookup (&file.file, - file.fs, - &dir, - &entry, - 0, - NULL, - ACCEPT_DIR | ACCEPT_PLAIN | MATCH_ANY, - name, - NULL) == 0) { - /* Display file info */ - printf ("%3.3s %9d %s %02d %04d %02d:%02d:%02d %s\n", - (dir.attr & ATTR_DIRECTORY) ? "dir" : " ", - __le32_to_cpu (dir.size), - month [DOS_MONTH (&dir) - 1], - DOS_DAY (&dir), - DOS_YEAR (&dir), - DOS_HOUR (&dir), - DOS_MINUTE (&dir), - DOS_SEC (&dir), - name); - - } - free (name); - return (0); -} - -#endif diff --git a/fs/fdos/fdos.h b/fs/fdos/fdos.h deleted file mode 100644 index e28c22f849..0000000000 --- a/fs/fdos/fdos.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * (C) Copyright 2002 - * Stäubli Faverges - <www.staubli.com> - * Pierre AUBERT p.aubert@staubli.com - * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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 _FDOS_H_ -#define _FDOS_H_ - - -#undef FDOS_DEBUG - -#ifdef FDOS_DEBUG -#define PRINTF(fmt,args...) printf (fmt ,##args) -#else -#define PRINTF(fmt,args...) -#endif - -/* Data structure describing media */ -typedef struct fs -{ - unsigned long tot_sectors; - - int cluster_size; - int num_clus; - - int fat_start; - int fat_len; - int nb_fat; - int num_fat; - - int dir_start; - int dir_len; - - unsigned char *fat_buf; - -} Fs_t; - -/* Data structure describing one file system slot */ -typedef struct slot { - int (*map) (struct fs *fs, - struct slot *file, - int where, - int *len); - unsigned long FileSize; - - unsigned short int FirstAbsCluNr; - unsigned short int PreviousAbsCluNr; - unsigned short int PreviousRelCluNr; - - Directory_t dir; -} Slot_t; - -typedef struct file { - char *name; - int Case; - Fs_t *fs; - Slot_t subdir; - Slot_t file; -} File_t; - - -/* dev.c */ -int dev_read (void *buffer, int where, int len); -int dev_open (void); -int check_dev (BootSector_t *boot, Fs_t *fs); - -/* fat.c */ -unsigned int fat_decode (Fs_t *fs, unsigned int num); -int read_fat (BootSector_t *boot, Fs_t *fs); - -/* vfat.c */ -int vfat_lookup (Slot_t *dir, - Fs_t *fs, - Directory_t *dirent, - int *entry, - int *vfat_start, - char *filename, - int flags, - char *outname, - Slot_t *file); - -/* subdir.c */ -char *basename (char *name); -int open_subdir (File_t *desc); -int open_file (Slot_t *file, Directory_t *dir); -int read_file (Fs_t *fs, - Slot_t *file, - char *buf, - int where, - int len); -void init_subdir (void); - -/* fs.c */ -int fs_init (Fs_t *fs); - - -#endif diff --git a/fs/fdos/fs.c b/fs/fdos/fs.c deleted file mode 100644 index 3b9d09e490..0000000000 --- a/fs/fdos/fs.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * (C) Copyright 2002 - * Stäubli Faverges - <www.staubli.com> - * Pierre AUBERT p.aubert@staubli.com - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> -#include <config.h> -#include <malloc.h> - -#if (CONFIG_COMMANDS & CFG_CMD_FDOS) - -#include "dos.h" -#include "fdos.h" - - -/*----------------------------------------------------------------------------- - * fill_fs -- Read info on file system - *----------------------------------------------------------------------------- - */ -static int fill_fs (BootSector_t *boot, Fs_t *fs) -{ - - fs -> fat_start = __le16_to_cpu (boot -> nrsvsect); - fs -> fat_len = __le16_to_cpu (boot -> fatlen); - fs -> nb_fat = boot -> nfat; - - fs -> dir_start = fs -> fat_start + fs -> nb_fat * fs -> fat_len; - fs -> dir_len = __le16_to_cpu (boot -> dirents) * MDIR_SIZE / SZ_STD_SECTOR; - fs -> cluster_size = boot -> clsiz; - fs -> num_clus = (fs -> tot_sectors - fs -> dir_start - fs -> dir_len) / fs -> cluster_size; - - return (0); -} - -/*----------------------------------------------------------------------------- - * fs_init -- - *----------------------------------------------------------------------------- - */ -int fs_init (Fs_t *fs) -{ - BootSector_t *boot; - - /* Initialize physical device */ - if (dev_open () < 0) { - PRINTF ("Unable to initialize the fdc\n"); - return (-1); - } - init_subdir (); - - /* Allocate space for read the boot sector */ - if ((boot = (BootSector_t *)malloc (sizeof (BootSector_t))) == NULL) { - PRINTF ("Unable to allocate space for boot sector\n"); - return (-1); - } - - /* read boot sector */ - if (dev_read (boot, 0, 1)){ - PRINTF ("Error during boot sector read\n"); - free (boot); - return (-1); - } - - /* we verify it'a a DOS diskette */ - if (boot -> jump [0] != JUMP_0_1 && boot -> jump [0] != JUMP_0_2) { - PRINTF ("Not a DOS diskette\n"); - free (boot); - return (-1); - } - - if (boot -> descr < MEDIA_STD) { - /* We handle only recent medias (type F0) */ - PRINTF ("unrecognized diskette type\n"); - free (boot); - return (-1); - } - - if (check_dev (boot, fs) < 0) { - PRINTF ("Bad diskette\n"); - free (boot); - return (-1); - } - - if (fill_fs (boot, fs) < 0) { - free (boot); - - return (-1); - } - - /* Read FAT */ - if (read_fat (boot, fs) < 0) { - free (boot); - return (-1); - } - - free (boot); - return (0); -} - -#endif diff --git a/fs/fdos/subdir.c b/fs/fdos/subdir.c deleted file mode 100644 index 97b25047ae..0000000000 --- a/fs/fdos/subdir.c +++ /dev/null @@ -1,348 +0,0 @@ -/* - * (C) Copyright 2002 - * Stäubli Faverges - <www.staubli.com> - * Pierre AUBERT p.aubert@staubli.com - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> -#include <config.h> -#include <malloc.h> - -#if (CONFIG_COMMANDS & CFG_CMD_FDOS) - -#include "dos.h" -#include "fdos.h" - -static int cache_sect; -static unsigned char cache [SZ_STD_SECTOR]; - - -#define min(x,y) ((x)<(y)?(x):(y)) - -static int descend (Slot_t *parent, - Fs_t *fs, - char *path); - -/*----------------------------------------------------------------------------- - * init_subdir -- - *----------------------------------------------------------------------------- - */ -void init_subdir (void) -{ - cache_sect = -1; -} -/*----------------------------------------------------------------------------- - * basename -- - *----------------------------------------------------------------------------- - */ -char *basename (char *name) -{ - register char *cptr; - - if (!name || !*name) { - return (""); - } - - for (cptr= name; *cptr++; ); - while (--cptr >= name) { - if (*cptr == '/') { - return (cptr + 1); - } - } - return(name); -} -/*----------------------------------------------------------------------------- - * root_map -- - *----------------------------------------------------------------------------- - */ -static int root_map (Fs_t *fs, Slot_t *file, int where, int *len) -{ - *len = min (*len, fs -> dir_len * SZ_STD_SECTOR - where); - if (*len < 0 ) { - *len = 0; - return (-1); - } - return fs -> dir_start * SZ_STD_SECTOR + where; -} -/*----------------------------------------------------------------------------- - * normal_map -- - *----------------------------------------------------------------------------- - */ -static int normal_map (Fs_t *fs, Slot_t *file, int where, int *len) -{ - int offset; - int NrClu; - unsigned short RelCluNr; - unsigned short CurCluNr; - unsigned short NewCluNr; - unsigned short AbsCluNr; - int clus_size; - - clus_size = fs -> cluster_size * SZ_STD_SECTOR; - offset = where % clus_size; - - *len = min (*len, file -> FileSize - where); - - if (*len < 0 ) { - *len = 0; - return (0); - } - - if (file -> FirstAbsCluNr < 2){ - *len = 0; - return (0); - } - - RelCluNr = where / clus_size; - - if (RelCluNr >= file -> PreviousRelCluNr){ - CurCluNr = file -> PreviousRelCluNr; - AbsCluNr = file -> PreviousAbsCluNr; - } else { - CurCluNr = 0; - AbsCluNr = file -> FirstAbsCluNr; - } - - - NrClu = (offset + *len - 1) / clus_size; - while (CurCluNr <= RelCluNr + NrClu) { - if (CurCluNr == RelCluNr){ - /* we have reached the beginning of our zone. Save - * coordinates */ - file -> PreviousRelCluNr = RelCluNr; - file -> PreviousAbsCluNr = AbsCluNr; - } - NewCluNr = fat_decode (fs, AbsCluNr); - if (NewCluNr == 1 || NewCluNr == 0) { - PRINTF("Fat problem while decoding %d %x\n", - AbsCluNr, NewCluNr); - return (-1); - } - if (CurCluNr == RelCluNr + NrClu) { - break; - } - - if (CurCluNr < RelCluNr && NewCluNr == FAT12_END) { - *len = 0; - return 0; - } - - if (CurCluNr >= RelCluNr && NewCluNr != AbsCluNr + 1) - break; - CurCluNr++; - AbsCluNr = NewCluNr; - } - - *len = min (*len, (1 + CurCluNr - RelCluNr) * clus_size - offset); - - return (((file -> PreviousAbsCluNr - 2) * fs -> cluster_size + - fs -> dir_start + fs -> dir_len) * - SZ_STD_SECTOR + offset); -} -/*----------------------------------------------------------------------------- - * open_subdir -- open the subdir containing the file - *----------------------------------------------------------------------------- - */ -int open_subdir (File_t *desc) -{ - char *pathname; - char *tmp, *s, *path; - char terminator; - - if ((pathname = (char *)malloc (MAX_PATH)) == NULL) { - return (-1); - } - - strcpy (pathname, desc -> name); - - /* Suppress file name */ - tmp = basename (pathname); - *tmp = '\0'; - - /* root directory init */ - desc -> subdir.FirstAbsCluNr = 0; - desc -> subdir.FileSize = -1; - desc -> subdir.map = root_map; - desc -> subdir.dir.attr = ATTR_DIRECTORY; - - tmp = pathname; - for (s = tmp; ; ++s) { - if (*s == '/' || *s == '\0') { - path = tmp; - terminator = *s; - *s = '\0'; - if (s != tmp && strcmp (path,".")) { - if (descend (&desc -> subdir, desc -> fs, path) < 0) { - free (pathname); - return (-1); - } - } - if (terminator == 0) { - break; - } - tmp = s + 1; - } - } - free (pathname); - return (0); -} -/*----------------------------------------------------------------------------- - * descend -- - *----------------------------------------------------------------------------- - */ -static int descend (Slot_t *parent, - Fs_t *fs, - char *path) -{ - int entry; - Slot_t SubDir; - - if(path[0] == '\0' || strcmp (path, ".") == 0) { - return (0); - } - - - entry = 0; - if (vfat_lookup (parent, - fs, - &(SubDir.dir), - &entry, - 0, - path, - ACCEPT_DIR | SINGLE | DO_OPEN, - 0, - &SubDir) == 0) { - *parent = SubDir; - return (0); - } - - if (strcmp(path, "..") == 0) { - parent -> FileSize = -1; - parent -> FirstAbsCluNr = 0; - parent -> map = root_map; - return (0); - } - return (-1); -} -/*----------------------------------------------------------------------------- - * open_file -- - *----------------------------------------------------------------------------- - */ -int open_file (Slot_t *file, Directory_t *dir) -{ - int first; - unsigned long size; - - first = __le16_to_cpu (dir -> start); - - if(first == 0 && - (dir -> attr & ATTR_DIRECTORY) != 0) { - file -> FirstAbsCluNr = 0; - file -> FileSize = -1; - file -> map = root_map; - return (0); - } - - if ((dir -> attr & ATTR_DIRECTORY) != 0) { - size = (1UL << 31) - 1; - } - else { - size = __le32_to_cpu (dir -> size); - } - - file -> map = normal_map; - file -> FirstAbsCluNr = first; - file -> PreviousRelCluNr = 0xffff; - file -> FileSize = size; - return (0); -} -/*----------------------------------------------------------------------------- - * read_file -- - *----------------------------------------------------------------------------- - */ -int read_file (Fs_t *fs, - Slot_t *file, - char *buf, - int where, - int len) -{ - int pos; - int read, nb, sect, offset; - - pos = file -> map (fs, file, where, &len); - if (pos < 0) { - return -1; - } - if (len == 0) { - return (0); - } - - /* Compute sector number */ - sect = pos / SZ_STD_SECTOR; - offset = pos % SZ_STD_SECTOR; - read = 0; - - if (offset) { - /* Read doesn't start at the sector beginning. We need to use our */ - /* cache */ - if (sect != cache_sect) { - if (dev_read (cache, sect, 1) < 0) { - return (-1); - } - cache_sect = sect; - } - nb = min (len, SZ_STD_SECTOR - offset); - - memcpy (buf, cache + offset, nb); - read += nb; - len -= nb; - sect += 1; - } - - if (len > SZ_STD_SECTOR) { - nb = (len - 1) / SZ_STD_SECTOR; - if (dev_read (buf + read, sect, nb) < 0) { - return ((read) ? read : -1); - } - /* update sector position */ - sect += nb; - - /* Update byte position */ - nb *= SZ_STD_SECTOR; - read += nb; - len -= nb; - } - - if (len) { - if (sect != cache_sect) { - if (dev_read (cache, sect, 1) < 0) { - return ((read) ? read : -1); - cache_sect = -1; - } - cache_sect = sect; - } - - memcpy (buf + read, cache, len); - read += len; - } - return (read); -} -#endif diff --git a/fs/fdos/vfat.c b/fs/fdos/vfat.c deleted file mode 100644 index 46a464b293..0000000000 --- a/fs/fdos/vfat.c +++ /dev/null @@ -1,357 +0,0 @@ -/* - * (C) Copyright 2002 - * Stäubli Faverges - <www.staubli.com> - * Pierre AUBERT p.aubert@staubli.com - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> -#include <config.h> - -#if (CONFIG_COMMANDS & CFG_CMD_FDOS) -#include <linux/ctype.h> - -#include "dos.h" -#include "fdos.h" - -static int dir_read (Fs_t *fs, - Slot_t *dir, - Directory_t *dirent, - int num, - struct vfat_state *v); - -static int unicode_read (char *in, char *out, int num); -static int match (const char *s, const char *p); -static unsigned char sum_shortname (char *name); -static int check_vfat (struct vfat_state *v, Directory_t *dir); -static char *conv_name (char *name, char *ext, char Case, char *ans); - - -/*----------------------------------------------------------------------------- - * clear_vfat -- - *----------------------------------------------------------------------------- - */ -static void clear_vfat (struct vfat_state *v) -{ - v -> subentries = 0; - v -> status = 0; -} - -/*----------------------------------------------------------------------------- - * vfat_lookup -- - *----------------------------------------------------------------------------- - */ -int vfat_lookup (Slot_t *dir, - Fs_t *fs, - Directory_t *dirent, - int *entry, - int *vfat_start, - char *filename, - int flags, - char *outname, - Slot_t *file) -{ - int found; - struct vfat_state vfat; - char newfile [VSE_NAMELEN]; - int vfat_present = 0; - - if (*entry == -1) { - return -1; - } - - found = 0; - clear_vfat (&vfat); - while (1) { - if (dir_read (fs, dir, dirent, *entry, &vfat) < 0) { - if (vfat_start) { - *vfat_start = *entry; - } - break; - } - (*entry)++; - - /* Empty slot */ - if (dirent -> name[0] == '\0'){ - if (vfat_start == 0) { - break; - } - continue; - } - - if (dirent -> attr == ATTR_VSE) { - /* VSE entry, continue */ - continue; - } - if ( (dirent -> name [0] == DELMARK) || - ((dirent -> attr & ATTR_DIRECTORY) != 0 && - (flags & ACCEPT_DIR) == 0) || - ((dirent -> attr & ATTR_VOLUME) != 0 && - (flags & ACCEPT_LABEL) == 0) || - (((dirent -> attr & (ATTR_DIRECTORY | ATTR_VOLUME)) == 0) && - (flags & ACCEPT_PLAIN) == 0)) { - clear_vfat (&vfat); - continue; - } - - vfat_present = check_vfat (&vfat, dirent); - if (vfat_start) { - *vfat_start = *entry - 1; - if (vfat_present) { - *vfat_start -= vfat.subentries; - } - } - - if (dirent -> attr & ATTR_VOLUME) { - strncpy (newfile, dirent -> name, 8); - newfile [8] = '\0'; - strncat (newfile, dirent -> ext, 3); - newfile [11] = '\0'; - } - else { - conv_name (dirent -> name, dirent -> ext, dirent -> Case, newfile); - } - - if (flags & MATCH_ANY) { - found = 1; - break; - } - - if ((vfat_present && match (vfat.name, filename)) || - (match (newfile, filename))) { - found = 1; - break; - } - clear_vfat (&vfat); - } - - if (found) { - if ((flags & DO_OPEN) && file) { - if (open_file (file, dirent) < 0) { - return (-1); - } - } - if (outname) { - if (vfat_present) { - strcpy (outname, vfat.name); - } - else { - strcpy (outname, newfile); - } - } - return (0); /* File found */ - } else { - *entry = -1; - return -1; /* File not found */ - } -} - -/*----------------------------------------------------------------------------- - * dir_read -- Read one directory entry - *----------------------------------------------------------------------------- - */ -static int dir_read (Fs_t *fs, - Slot_t *dir, - Directory_t *dirent, - int num, - struct vfat_state *v) -{ - - /* read the directory entry */ - if (read_file (fs, - dir, - (char *)dirent, - num * MDIR_SIZE, - MDIR_SIZE) != MDIR_SIZE) { - return (-1); - } - - if (v && (dirent -> attr == ATTR_VSE)) { - struct vfat_subentry *vse; - unsigned char id, last_flag; - char *c; - - vse = (struct vfat_subentry *) dirent; - id = vse -> id & VSE_MASK; - last_flag = (vse -> id & VSE_LAST); - if (id > MAX_VFAT_SUBENTRIES) { - /* Invalid VSE entry */ - return (-1); - } - - - /* Decode VSE */ - if(v -> sum != vse -> sum) { - clear_vfat (v); - v -> sum = vse -> sum; - } - - - v -> status |= 1 << (id - 1); - if (last_flag) { - v -> subentries = id; - } - - c = &(v -> name [VSE_NAMELEN * (id - 1)]); - c += unicode_read (vse->text1, c, VSE1SIZE); - c += unicode_read (vse->text2, c, VSE2SIZE); - c += unicode_read (vse->text3, c, VSE3SIZE); - - if (last_flag) { - *c = '\0'; /* Null terminate long name */ - } - - } - return (0); -} - -/*----------------------------------------------------------------------------- - * unicode_read -- - *----------------------------------------------------------------------------- - */ -static int unicode_read (char *in, char *out, int num) -{ - int j; - - for (j = 0; j < num; ++j) { - if (in [1]) - *out = '_'; - else - *out = in [0]; - out ++; - in += 2; - } - return num; -} - -/*----------------------------------------------------------------------------- - * match -- - *----------------------------------------------------------------------------- - */ -static int match (const char *s, const char *p) -{ - - for (; *p != '\0'; ) { - if (toupper (*s) != toupper (*p)) { - return (0); - } - p++; - s++; - } - - if (*s != '\0') { - return (0); - } - else { - return (1); - } -} -/*----------------------------------------------------------------------------- - * sum_shortname -- - *----------------------------------------------------------------------------- - */ -static unsigned char sum_shortname (char *name) -{ - unsigned char sum; - int j; - - for (j = sum = 0; j < 11; ++j) { - sum = ((sum & 1) ? 0x80 : 0) + (sum >> 1) + - (name [j] ? name [j] : ' '); - } - return (sum); -} -/*----------------------------------------------------------------------------- - * check_vfat -- - * Return 1 if long name is valid, 0 else - *----------------------------------------------------------------------------- - */ -static int check_vfat (struct vfat_state *v, Directory_t *dir) -{ - char name[12]; - - if (v -> subentries == 0) { - return 0; - } - - strncpy (name, dir -> name, 8); - strncpy (name + 8, dir -> ext, 3); - name [11] = '\0'; - - if (v -> sum != sum_shortname (name)) { - return 0; - } - - if( (v -> status & ((1 << v -> subentries) - 1)) != - (1 << v -> subentries) - 1) { - return 0; - } - v->name [VSE_NAMELEN * v -> subentries] = 0; - - return 1; -} -/*----------------------------------------------------------------------------- - * conv_name -- - *----------------------------------------------------------------------------- - */ -static char *conv_name (char *name, char *ext, char Case, char *ans) -{ - char tname [9], text [4]; - int i; - - i = 0; - while (i < 8 && name [i] != ' ' && name [i] != '\0') { - tname [i] = name [i]; - i++; - } - tname [i] = '\0'; - - if (Case & BASECASE) { - for (i = 0; i < 8 && tname [i]; i++) { - tname [i] = tolower (tname [i]); - } - } - - i = 0; - while (i < 3 && ext [i] != ' ' && ext [i] != '\0') { - text [i] = ext [i]; - i++; - } - text [i] = '\0'; - - if (Case & EXTCASE){ - for (i = 0; i < 3 && text [i]; i++) { - text [i] = tolower (text [i]); - } - } - - if (*text) { - strcpy (ans, tname); - strcat (ans, "."); - strcat (ans, text); - } - else { - strcpy(ans, tname); - } - return (ans); -} - - -#endif diff --git a/fs/jffs2/Makefile b/fs/jffs2/Makefile deleted file mode 100644 index c1357d0aa5..0000000000 --- a/fs/jffs2/Makefile +++ /dev/null @@ -1,50 +0,0 @@ -# -# (C) Copyright 2000-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)libjffs2.a - -AOBJS = -COBJS = jffs2_1pass.o compr_rtime.o compr_rubin.o compr_zlib.o mini_inflate.o -COBJS += compr_lzo.o compr_lzari.o - -SRCS := $(AOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(AOBJS) $(COBJS)) - -#CPPFLAGS += - -all: $(LIB) $(AOBJS) - -$(LIB): $(obj).depend $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/fs/jffs2/compr_lzari.c b/fs/jffs2/compr_lzari.c deleted file mode 100644 index 828b6e5515..0000000000 --- a/fs/jffs2/compr_lzari.c +++ /dev/null @@ -1,262 +0,0 @@ -/* - * JFFS2 -- Journalling Flash File System, Version 2. - * - * Copyright (C) 2004 Patrik Kluba, - * University of Szeged, Hungary - * - * For licensing information, see the file 'LICENCE' in the - * jffs2 directory. - * - * $Id: compr_lzari.c,v 1.3 2004/06/23 16:34:39 havasi Exp $ - * - */ - -/* - Lempel-Ziv-Arithmetic coding compression module for jffs2 - Based on the LZARI source included in LDS (lossless datacompression sources) -*/ - -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ - -/* -Original copyright follows: - -************************************************************** - LZARI.C -- A Data Compression Program - (tab = 4 spaces) -************************************************************** - 4/7/1989 Haruhiko Okumura - Use, distribute, and modify this program freely. - Please send me your improved versions. - PC-VAN SCIENCE - NIFTY-Serve PAF01022 - CompuServe 74050,1022 -************************************************************** - -LZARI.C (c)1989 by Haruyasu Yoshizaki, Haruhiko Okumura, and Kenji Rikitake. -All rights reserved. Permission granted for non-commercial use. - -*/ - -/* - - 2004-02-18 pajko <pajko(AT)halom(DOT)u-szeged(DOT)hu> - Removed unused variables and fixed no return value - - 2004-02-16 pajko <pajko(AT)halom(DOT)u-szeged(DOT)hu> - Initial release - -*/ - - -#include <config.h> -#if ((CONFIG_COMMANDS & CFG_CMD_JFFS2) && defined(CONFIG_JFFS2_LZO_LZARI)) - -#include <linux/stddef.h> -#include <jffs2/jffs2.h> - - -#define N 4096 /* size of ring buffer */ -#define F 60 /* upper limit for match_length */ -#define THRESHOLD 2 /* encode string into position and length - if match_length is greater than this */ -#define NIL N /* index for root of binary search trees */ - -static unsigned char - text_buf[N + F - 1]; /* ring buffer of size N, - with extra F-1 bytes to facilitate string comparison */ - -/********** Arithmetic Compression **********/ - -/* If you are not familiar with arithmetic compression, you should read - I. E. Witten, R. M. Neal, and J. G. Cleary, - Communications of the ACM, Vol. 30, pp. 520-540 (1987), - from which much have been borrowed. */ - -#define M 15 - -/* Q1 (= 2 to the M) must be sufficiently large, but not so - large as the unsigned long 4 * Q1 * (Q1 - 1) overflows. */ - -#define Q1 (1UL << M) -#define Q2 (2 * Q1) -#define Q3 (3 * Q1) -#define Q4 (4 * Q1) -#define MAX_CUM (Q1 - 1) - -#define N_CHAR (256 - THRESHOLD + F) - /* character code = 0, 1, ..., N_CHAR - 1 */ - -static unsigned long char_to_sym[N_CHAR], sym_to_char[N_CHAR + 1]; -static unsigned long - sym_freq[N_CHAR + 1], /* frequency for symbols */ - sym_cum[N_CHAR + 1], /* cumulative freq for symbols */ - position_cum[N + 1]; /* cumulative freq for positions */ - -static void StartModel(void) /* Initialize model */ -{ - unsigned long ch, sym, i; - - sym_cum[N_CHAR] = 0; - for (sym = N_CHAR; sym >= 1; sym--) { - ch = sym - 1; - char_to_sym[ch] = sym; sym_to_char[sym] = ch; - sym_freq[sym] = 1; - sym_cum[sym - 1] = sym_cum[sym] + sym_freq[sym]; - } - sym_freq[0] = 0; /* sentinel (!= sym_freq[1]) */ - position_cum[N] = 0; - for (i = N; i >= 1; i--) - position_cum[i - 1] = position_cum[i] + 10000 / (i + 200); - /* empirical distribution function (quite tentative) */ - /* Please devise a better mechanism! */ -} - -static void UpdateModel(unsigned long sym) -{ - unsigned long c, ch_i, ch_sym; - unsigned long i; - if (sym_cum[0] >= MAX_CUM) { - c = 0; - for (i = N_CHAR; i > 0; i--) { - sym_cum[i] = c; - c += (sym_freq[i] = (sym_freq[i] + 1) >> 1); - } - sym_cum[0] = c; - } - for (i = sym; sym_freq[i] == sym_freq[i - 1]; i--) ; - if (i < sym) { - ch_i = sym_to_char[i]; ch_sym = sym_to_char[sym]; - sym_to_char[i] = ch_sym; sym_to_char[sym] = ch_i; - char_to_sym[ch_i] = sym; char_to_sym[ch_sym] = i; - } - sym_freq[i]++; - while (--i > 0) sym_cum[i]++; - sym_cum[0]++; -} - -static unsigned long BinarySearchSym(unsigned long x) - /* 1 if x >= sym_cum[1], - N_CHAR if sym_cum[N_CHAR] > x, - i such that sym_cum[i - 1] > x >= sym_cum[i] otherwise */ -{ - unsigned long i, j, k; - - i = 1; j = N_CHAR; - while (i < j) { - k = (i + j) / 2; - if (sym_cum[k] > x) i = k + 1; else j = k; - } - return i; -} - -unsigned long BinarySearchPos(unsigned long x) - /* 0 if x >= position_cum[1], - N - 1 if position_cum[N] > x, - i such that position_cum[i] > x >= position_cum[i + 1] otherwise */ -{ - unsigned long i, j, k; - - i = 1; j = N; - while (i < j) { - k = (i + j) / 2; - if (position_cum[k] > x) i = k + 1; else j = k; - } - return i - 1; -} - -static int Decode(unsigned char *srcbuf, unsigned char *dstbuf, unsigned long srclen, - unsigned long dstlen) /* Just the reverse of Encode(). */ -{ - unsigned long i, r, j, k, c, range, sym; - unsigned char *ip, *op; - unsigned char *srcend = srcbuf + srclen; - unsigned char *dstend = dstbuf + dstlen; - unsigned char buffer = 0; - unsigned char mask = 0; - unsigned long low = 0; - unsigned long high = Q4; - unsigned long value = 0; - - ip = srcbuf; - op = dstbuf; - for (i = 0; i < M + 2; i++) { - value *= 2; - if ((mask >>= 1) == 0) { - buffer = (ip >= srcend) ? 0 : *(ip++); - mask = 128; - } - value += ((buffer & mask) != 0); - } - - StartModel(); - for (i = 0; i < N - F; i++) text_buf[i] = ' '; - r = N - F; - - while (op < dstend) { - range = high - low; - sym = BinarySearchSym((unsigned long) - (((value - low + 1) * sym_cum[0] - 1) / range)); - high = low + (range * sym_cum[sym - 1]) / sym_cum[0]; - low += (range * sym_cum[sym ]) / sym_cum[0]; - for ( ; ; ) { - if (low >= Q2) { - value -= Q2; low -= Q2; high -= Q2; - } else if (low >= Q1 && high <= Q3) { - value -= Q1; low -= Q1; high -= Q1; - } else if (high > Q2) break; - low += low; high += high; - value *= 2; - if ((mask >>= 1) == 0) { - buffer = (ip >= srcend) ? 0 : *(ip++); - mask = 128; - } - value += ((buffer & mask) != 0); - } - c = sym_to_char[sym]; - UpdateModel(sym); - if (c < 256) { - if (op >= dstend) return -1; - *(op++) = c; - text_buf[r++] = c; - r &= (N - 1); - } else { - j = c - 255 + THRESHOLD; - range = high - low; - i = BinarySearchPos((unsigned long) - (((value - low + 1) * position_cum[0] - 1) / range)); - high = low + (range * position_cum[i ]) / position_cum[0]; - low += (range * position_cum[i + 1]) / position_cum[0]; - for ( ; ; ) { - if (low >= Q2) { - value -= Q2; low -= Q2; high -= Q2; - } else if (low >= Q1 && high <= Q3) { - value -= Q1; low -= Q1; high -= Q1; - } else if (high > Q2) break; - low += low; high += high; - value *= 2; - if ((mask >>= 1) == 0) { - buffer = (ip >= srcend) ? 0 : *(ip++); - mask = 128; - } - value += ((buffer & mask) != 0); - } - i = (r - i - 1) & (N - 1); - for (k = 0; k < j; k++) { - c = text_buf[(i + k) & (N - 1)]; - if (op >= dstend) return -1; - *(op++) = c; - text_buf[r++] = c; - r &= (N - 1); - } - } - } - return 0; -} - -int lzari_decompress(unsigned char *data_in, unsigned char *cpage_out, - u32 srclen, u32 destlen) -{ - return Decode(data_in, cpage_out, srclen, destlen); -} -#endif /* ((CONFIG_COMMANDS & CFG_CMD_JFFS2) && defined(CONFIG_JFFS2_LZO_LZARI)) */ diff --git a/fs/jffs2/compr_lzo.c b/fs/jffs2/compr_lzo.c deleted file mode 100644 index b6c590ac8f..0000000000 --- a/fs/jffs2/compr_lzo.c +++ /dev/null @@ -1,405 +0,0 @@ -/* - * JFFS2 -- Journalling Flash File System, Version 2. - * - * Copyright (C) 2004 Patrik Kluba, - * University of Szeged, Hungary - * - * For licensing information, see the file 'LICENCE' in the - * jffs2 directory. - * - * $Id: compr_lzo.c,v 1.3 2004/06/23 16:34:39 havasi Exp $ - * - */ - -/* - LZO1X-1 (and -999) compression module for jffs2 - based on the original LZO sources -*/ - -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ - -/* - Original copyright notice follows: - - lzo1x_9x.c -- implementation of the LZO1X-999 compression algorithm - lzo_ptr.h -- low-level pointer constructs - lzo_swd.ch -- sliding window dictionary - lzoconf.h -- configuration for the LZO real-time data compression library - lzo_mchw.ch -- matching functions using a window - minilzo.c -- mini subset of the LZO real-time data compression library - config1x.h -- configuration for the LZO1X algorithm - lzo1x.h -- public interface of the LZO1X compression algorithm - - These files are part of the LZO real-time data compression library. - - Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer - All Rights Reserved. - - The LZO library 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. - - The LZO library 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 the LZO library; see the file COPYING. - If not, write to the Free Software Foundation, Inc., - 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - Markus F.X.J. Oberhumer - <markus@oberhumer.com> -*/ - -/* - - 2004-02-16 pajko <pajko(AT)halom(DOT)u-szeged(DOT)hu> - Initial release - -removed all 16 bit code - -all sensitive data will be on 4 byte boundary - -removed check parts for library use - -removed all but LZO1X-* compression - -*/ - - -#include <config.h> -#if ((CONFIG_COMMANDS & CFG_CMD_JFFS2) && defined(CONFIG_JFFS2_LZO_LZARI)) - -#include <linux/stddef.h> -#include <jffs2/jffs2.h> -#include <jffs2/compr_rubin.h> - -/* Integral types that have *exactly* the same number of bits as a lzo_voidp */ -typedef unsigned long lzo_ptr_t; -typedef long lzo_sptr_t; - -/* data type definitions */ -#define U32 unsigned long -#define S32 signed long -#define I32 long -#define U16 unsigned short -#define S16 signed short -#define I16 short -#define U8 unsigned char -#define S8 signed char -#define I8 char - -#define M1_MAX_OFFSET 0x0400 -#define M2_MAX_OFFSET 0x0800 -#define M3_MAX_OFFSET 0x4000 -#define M4_MAX_OFFSET 0xbfff - -#define __COPY4(dst,src) * (lzo_uint32p)(dst) = * (const lzo_uint32p)(src) -#define COPY4(dst,src) __COPY4((lzo_ptr_t)(dst),(lzo_ptr_t)(src)) - -#define TEST_IP (ip < ip_end) -#define TEST_OP (op <= op_end) - -#define NEED_IP(x) \ - if ((lzo_uint)(ip_end - ip) < (lzo_uint)(x)) goto input_overrun -#define NEED_OP(x) \ - if ((lzo_uint)(op_end - op) < (lzo_uint)(x)) goto output_overrun -#define TEST_LOOKBEHIND(m_pos,out) if (m_pos < out) goto lookbehind_overrun - -typedef U32 lzo_uint32; -typedef I32 lzo_int32; -typedef U32 lzo_uint; -typedef I32 lzo_int; -typedef int lzo_bool; - -#define lzo_byte U8 -#define lzo_bytep U8 * -#define lzo_charp char * -#define lzo_voidp void * -#define lzo_shortp short * -#define lzo_ushortp unsigned short * -#define lzo_uint32p lzo_uint32 * -#define lzo_int32p lzo_int32 * -#define lzo_uintp lzo_uint * -#define lzo_intp lzo_int * -#define lzo_voidpp lzo_voidp * -#define lzo_bytepp lzo_bytep * -#define lzo_sizeof_dict_t sizeof(lzo_bytep) - -#define LZO_E_OK 0 -#define LZO_E_ERROR (-1) -#define LZO_E_OUT_OF_MEMORY (-2) /* not used right now */ -#define LZO_E_NOT_COMPRESSIBLE (-3) /* not used right now */ -#define LZO_E_INPUT_OVERRUN (-4) -#define LZO_E_OUTPUT_OVERRUN (-5) -#define LZO_E_LOOKBEHIND_OVERRUN (-6) -#define LZO_E_EOF_NOT_FOUND (-7) -#define LZO_E_INPUT_NOT_CONSUMED (-8) - -#define PTR(a) ((lzo_ptr_t) (a)) -#define PTR_LINEAR(a) PTR(a) -#define PTR_ALIGNED_4(a) ((PTR_LINEAR(a) & 3) == 0) -#define PTR_ALIGNED_8(a) ((PTR_LINEAR(a) & 7) == 0) -#define PTR_ALIGNED2_4(a,b) (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 3) == 0) -#define PTR_ALIGNED2_8(a,b) (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 7) == 0) -#define PTR_LT(a,b) (PTR(a) < PTR(b)) -#define PTR_GE(a,b) (PTR(a) >= PTR(b)) -#define PTR_DIFF(a,b) ((lzo_ptrdiff_t) (PTR(a) - PTR(b))) -#define pd(a,b) ((lzo_uint) ((a)-(b))) - -typedef ptrdiff_t lzo_ptrdiff_t; - -static int -lzo1x_decompress (const lzo_byte * in, lzo_uint in_len, - lzo_byte * out, lzo_uintp out_len, lzo_voidp wrkmem) -{ - register lzo_byte *op; - register const lzo_byte *ip; - register lzo_uint t; - - register const lzo_byte *m_pos; - - const lzo_byte *const ip_end = in + in_len; - lzo_byte *const op_end = out + *out_len; - - *out_len = 0; - - op = out; - ip = in; - - if (*ip > 17) - { - t = *ip++ - 17; - if (t < 4) - goto match_next; - NEED_OP (t); - NEED_IP (t + 1); - do - *op++ = *ip++; - while (--t > 0); - goto first_literal_run; - } - - while (TEST_IP && TEST_OP) - { - t = *ip++; - if (t >= 16) - goto match; - if (t == 0) - { - NEED_IP (1); - while (*ip == 0) - { - t += 255; - ip++; - NEED_IP (1); - } - t += 15 + *ip++; - } - NEED_OP (t + 3); - NEED_IP (t + 4); - if (PTR_ALIGNED2_4 (op, ip)) - { - COPY4 (op, ip); - - op += 4; - ip += 4; - if (--t > 0) - { - if (t >= 4) - { - do - { - COPY4 (op, ip); - op += 4; - ip += 4; - t -= 4; - } - while (t >= 4); - if (t > 0) - do - *op++ = *ip++; - while (--t > 0); - } - else - do - *op++ = *ip++; - while (--t > 0); - } - } - else - { - *op++ = *ip++; - *op++ = *ip++; - *op++ = *ip++; - do - *op++ = *ip++; - while (--t > 0); - } - first_literal_run: - - t = *ip++; - if (t >= 16) - goto match; - - m_pos = op - (1 + M2_MAX_OFFSET); - m_pos -= t >> 2; - m_pos -= *ip++ << 2; - TEST_LOOKBEHIND (m_pos, out); - NEED_OP (3); - *op++ = *m_pos++; - *op++ = *m_pos++; - *op++ = *m_pos; - - goto match_done; - - while (TEST_IP && TEST_OP) - { - match: - if (t >= 64) - { - m_pos = op - 1; - m_pos -= (t >> 2) & 7; - m_pos -= *ip++ << 3; - t = (t >> 5) - 1; - TEST_LOOKBEHIND (m_pos, out); - NEED_OP (t + 3 - 1); - goto copy_match; - - } - else if (t >= 32) - { - t &= 31; - if (t == 0) - { - NEED_IP (1); - while (*ip == 0) - { - t += 255; - ip++; - NEED_IP (1); - } - t += 31 + *ip++; - } - - m_pos = op - 1; - m_pos -= (ip[0] >> 2) + (ip[1] << 6); - - ip += 2; - } - else if (t >= 16) - { - m_pos = op; - m_pos -= (t & 8) << 11; - - t &= 7; - if (t == 0) - { - NEED_IP (1); - while (*ip == 0) - { - t += 255; - ip++; - NEED_IP (1); - } - t += 7 + *ip++; - } - - m_pos -= (ip[0] >> 2) + (ip[1] << 6); - - ip += 2; - if (m_pos == op) - goto eof_found; - m_pos -= 0x4000; - } - else - { - - m_pos = op - 1; - m_pos -= t >> 2; - m_pos -= *ip++ << 2; - TEST_LOOKBEHIND (m_pos, out); - NEED_OP (2); - *op++ = *m_pos++; - *op++ = *m_pos; - - goto match_done; - } - - TEST_LOOKBEHIND (m_pos, out); - NEED_OP (t + 3 - 1); - if (t >= 2 * 4 - (3 - 1) - && PTR_ALIGNED2_4 (op, m_pos)) - { - COPY4 (op, m_pos); - op += 4; - m_pos += 4; - t -= 4 - (3 - 1); - do - { - COPY4 (op, m_pos); - op += 4; - m_pos += 4; - t -= 4; - } - while (t >= 4); - if (t > 0) - do - *op++ = *m_pos++; - while (--t > 0); - } - else - - { - copy_match: - *op++ = *m_pos++; - *op++ = *m_pos++; - do - *op++ = *m_pos++; - while (--t > 0); - } - - match_done: - t = ip[-2] & 3; - - if (t == 0) - break; - - match_next: - NEED_OP (t); - NEED_IP (t + 1); - do - *op++ = *ip++; - while (--t > 0); - t = *ip++; - } - } - *out_len = op - out; - return LZO_E_EOF_NOT_FOUND; - - eof_found: - *out_len = op - out; - return (ip == ip_end ? LZO_E_OK : - (ip < - ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); - - input_overrun: - *out_len = op - out; - return LZO_E_INPUT_OVERRUN; - - output_overrun: - *out_len = op - out; - return LZO_E_OUTPUT_OVERRUN; - - lookbehind_overrun: - *out_len = op - out; - return LZO_E_LOOKBEHIND_OVERRUN; -} - -int lzo_decompress(unsigned char *data_in, unsigned char *cpage_out, - u32 srclen, u32 destlen) -{ - lzo_uint outlen = destlen; - return lzo1x_decompress (data_in, srclen, cpage_out, &outlen, NULL); -} - -#endif /* ((CONFIG_COMMANDS & CFG_CMD_JFFS2) && defined(CONFIG_JFFS2_LZO_LZARI)) */ diff --git a/fs/jffs2/compr_rtime.c b/fs/jffs2/compr_rtime.c deleted file mode 100644 index 9bb4f1bcb6..0000000000 --- a/fs/jffs2/compr_rtime.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * JFFS2 -- Journalling Flash File System, Version 2. - * - * Copyright (C) 2001 Red Hat, Inc. - * - * Created by Arjan van de Ven <arjanv@redhat.com> - * - * The original JFFS, from which the design for JFFS2 was derived, - * was designed and implemented by Axis Communications AB. - * - * The contents of this file are subject to the Red Hat eCos Public - * License Version 1.1 (the "Licence"); you may not use this file - * except in compliance with the Licence. You may obtain a copy of - * the Licence at http://www.redhat.com/ - * - * Software distributed under the Licence is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. - * See the Licence for the specific language governing rights and - * limitations under the Licence. - * - * The Original Code is JFFS2 - Journalling Flash File System, version 2 - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License version 2 (the "GPL"), in - * which case the provisions of the GPL are applicable instead of the - * above. If you wish to allow the use of your version of this file - * only under the terms of the GPL and not to allow others to use your - * version of this file under the RHEPL, indicate your decision by - * deleting the provisions above and replace them with the notice and - * other provisions required by the GPL. If you do not delete the - * provisions above, a recipient may use your version of this file - * under either the RHEPL or the GPL. - * - * $Id: compr_rtime.c,v 1.2 2002/01/24 22:58:42 rfeany Exp $ - * - * - * Very simple lz77-ish encoder. - * - * Theory of operation: Both encoder and decoder have a list of "last - * occurances" for every possible source-value; after sending the - * first source-byte, the second byte indicated the "run" length of - * matches - * - * The algorithm is intended to only send "whole bytes", no bit-messing. - * - */ - -#include <config.h> -#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) - -#include <jffs2/jffs2.h> - -void rtime_decompress(unsigned char *data_in, unsigned char *cpage_out, - u32 srclen, u32 destlen) -{ - int positions[256]; - int outpos; - int pos; - int i; - - outpos = pos = 0; - - for (i = 0; i < 256; positions[i++] = 0); - - while (outpos<destlen) { - unsigned char value; - int backoffs; - int repeat; - - value = data_in[pos++]; - cpage_out[outpos++] = value; /* first the verbatim copied byte */ - repeat = data_in[pos++]; - backoffs = positions[value]; - - positions[value]=outpos; - if (repeat) { - if (backoffs + repeat >= outpos) { - while(repeat) { - cpage_out[outpos++] = cpage_out[backoffs++]; - repeat--; - } - } else { - for (i = 0; i < repeat; i++) - *(cpage_out + outpos + i) = *(cpage_out + backoffs + i); - outpos+=repeat; - } - } - } -} - -#endif /* CFG_CMD_JFFS2 */ diff --git a/fs/jffs2/compr_rubin.c b/fs/jffs2/compr_rubin.c deleted file mode 100644 index 74577d9c62..0000000000 --- a/fs/jffs2/compr_rubin.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * JFFS2 -- Journalling Flash File System, Version 2. - * - * Copyright (C) 2001 Red Hat, Inc. - * - * Created by Arjan van de Ven <arjanv@redhat.com> - * - * Heavily modified by Russ Dill <Russ.Dill@asu.edu> in an attempt at - * a little more speed. - * - * The original JFFS, from which the design for JFFS2 was derived, - * was designed and implemented by Axis Communications AB. - * - * The contents of this file are subject to the Red Hat eCos Public - * License Version 1.1 (the "Licence"); you may not use this file - * except in compliance with the Licence. You may obtain a copy of - * the Licence at http://www.redhat.com/ - * - * Software distributed under the Licence is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. - * See the Licence for the specific language governing rights and - * limitations under the Licence. - * - * The Original Code is JFFS2 - Journalling Flash File System, version 2 - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License version 2 (the "GPL"), in - * which case the provisions of the GPL are applicable instead of the - * above. If you wish to allow the use of your version of this file - * only under the terms of the GPL and not to allow others to use your - * version of this file under the RHEPL, indicate your decision by - * deleting the provisions above and replace them with the notice and - * other provisions required by the GPL. If you do not delete the - * provisions above, a recipient may use your version of this file - * under either the RHEPL or the GPL. - * - * $Id: compr_rubin.c,v 1.2 2002/01/24 22:58:42 rfeany Exp $ - * - */ - -#include <config.h> -#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) - -#include <jffs2/jffs2.h> -#include <jffs2/compr_rubin.h> - - -void rubin_do_decompress(unsigned char *bits, unsigned char *in, - unsigned char *page_out, __u32 destlen) -{ - register char *curr = (char *)page_out; - char *end = (char *)(page_out + destlen); - register unsigned long temp; - register unsigned long result; - register unsigned long p; - register unsigned long q; - register unsigned long rec_q; - register unsigned long bit; - register long i0; - unsigned long i; - - /* init_pushpull */ - temp = *(u32 *) in; - bit = 16; - - /* init_rubin */ - q = 0; - p = (long) (2 * UPPER_BIT_RUBIN); - - /* init_decode */ - rec_q = (in[0] << 8) | in[1]; - - while (curr < end) { - /* in byte */ - - result = 0; - for (i = 0; i < 8; i++) { - /* decode */ - - while ((q & UPPER_BIT_RUBIN) || ((p + q) <= UPPER_BIT_RUBIN)) { - q &= ~UPPER_BIT_RUBIN; - q <<= 1; - p <<= 1; - rec_q &= ~UPPER_BIT_RUBIN; - rec_q <<= 1; - rec_q |= (temp >> (bit++ ^ 7)) & 1; - if (bit > 31) { - u32 *p = (u32 *)in; - bit = 0; - temp = *(++p); - in = (unsigned char *)p; - } - } - i0 = (bits[i] * p) >> 8; - - if (i0 <= 0) i0 = 1; - /* if it fails, it fails, we have our crc - if (i0 >= p) i0 = p - 1; */ - - result >>= 1; - if (rec_q < q + i0) { - /* result |= 0x00; */ - p = i0; - } else { - result |= 0x80; - p -= i0; - q += i0; - } - } - *(curr++) = result; - } -} - -void dynrubin_decompress(unsigned char *data_in, unsigned char *cpage_out, - unsigned long sourcelen, unsigned long dstlen) -{ - unsigned char bits[8]; - int c; - - for (c=0; c<8; c++) - bits[c] = (256 - data_in[c]); - - rubin_do_decompress(bits, data_in+8, cpage_out, dstlen); -} - -#endif /* CFG_CMD_JFFS2 */ diff --git a/fs/jffs2/compr_zlib.c b/fs/jffs2/compr_zlib.c deleted file mode 100644 index 1b35585eee..0000000000 --- a/fs/jffs2/compr_zlib.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * JFFS2 -- Journalling Flash File System, Version 2. - * - * Copyright (C) 2001 Red Hat, Inc. - * - * Created by David Woodhouse <dwmw2@cambridge.redhat.com> - * - * The original JFFS, from which the design for JFFS2 was derived, - * was designed and implemented by Axis Communications AB. - * - * The contents of this file are subject to the Red Hat eCos Public - * License Version 1.1 (the "Licence"); you may not use this file - * except in compliance with the Licence. You may obtain a copy of - * the Licence at http://www.redhat.com/ - * - * Software distributed under the Licence is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. - * See the Licence for the specific language governing rights and - * limitations under the Licence. - * - * The Original Code is JFFS2 - Journalling Flash File System, version 2 - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License version 2 (the "GPL"), in - * which case the provisions of the GPL are applicable instead of the - * above. If you wish to allow the use of your version of this file - * only under the terms of the GPL and not to allow others to use your - * version of this file under the RHEPL, indicate your decision by - * deleting the provisions above and replace them with the notice and - * other provisions required by the GPL. If you do not delete the - * provisions above, a recipient may use your version of this file - * under either the RHEPL or the GPL. - * - * $Id: compr_zlib.c,v 1.2 2002/01/24 22:58:42 rfeany Exp $ - * - */ - -#include <common.h> -#include <config.h> -#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) - -#include <jffs2/jffs2.h> -#include <jffs2/mini_inflate.h> - -long zlib_decompress(unsigned char *data_in, unsigned char *cpage_out, - __u32 srclen, __u32 destlen) -{ - return (decompress_block(cpage_out, data_in + 2, ldr_memcpy)); - -} - -#endif /* CFG_CMD_JFFS2 */ diff --git a/fs/jffs2/jffs2_1pass.c b/fs/jffs2/jffs2_1pass.c deleted file mode 100644 index e156cd3811..0000000000 --- a/fs/jffs2/jffs2_1pass.c +++ /dev/null @@ -1,1325 +0,0 @@ -/* -------------------------------------------------------------------------- - * Filename: jffs2.c - * Version: $Id: jffs2_1pass.c,v 1.7 2002/01/25 01:56:47 nyet Exp $ - * Copyright: Copyright (C) 2001, Russ Dill - * Author: Russ Dill <Russ.Dill@asu.edu> - * Description: Module to load kernel from jffs2 - *-----------------------------------------------------------------------*/ -/* - * some portions of this code are taken from jffs2, and as such, the - * following copyright notice is included. - * - * JFFS2 -- Journalling Flash File System, Version 2. - * - * Copyright (C) 2001 Red Hat, Inc. - * - * Created by David Woodhouse <dwmw2@cambridge.redhat.com> - * - * The original JFFS, from which the design for JFFS2 was derived, - * was designed and implemented by Axis Communications AB. - * - * The contents of this file are subject to the Red Hat eCos Public - * License Version 1.1 (the "Licence"); you may not use this file - * except in compliance with the Licence. You may obtain a copy of - * the Licence at http://www.redhat.com/ - * - * Software distributed under the Licence is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. - * See the Licence for the specific language governing rights and - * limitations under the Licence. - * - * The Original Code is JFFS2 - Journalling Flash File System, version 2 - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License version 2 (the "GPL"), in - * which case the provisions of the GPL are applicable instead of the - * above. If you wish to allow the use of your version of this file - * only under the terms of the GPL and not to allow others to use your - * version of this file under the RHEPL, indicate your decision by - * deleting the provisions above and replace them with the notice and - * other provisions required by the GPL. If you do not delete the - * provisions above, a recipient may use your version of this file - * under either the RHEPL or the GPL. - * - * $Id: jffs2_1pass.c,v 1.7 2002/01/25 01:56:47 nyet Exp $ - * - */ - -/* Ok, so anyone who knows the jffs2 code will probably want to get a papar - * bag to throw up into before reading this code. I looked through the jffs2 - * code, the caching scheme is very elegant. I tried to keep the version - * for a bootloader as small and simple as possible. Instead of worring about - * unneccesary data copies, node scans, etc, I just optimized for the known - * common case, a kernel, which looks like: - * (1) most pages are 4096 bytes - * (2) version numbers are somewhat sorted in acsending order - * (3) multiple compressed blocks making up one page is uncommon - * - * So I create a linked list of decending version numbers (insertions at the - * head), and then for each page, walk down the list, until a matching page - * with 4096 bytes is found, and then decompress the watching pages in - * reverse order. - * - */ - -/* - * Adapted by Nye Liu <nyet@zumanetworks.com> and - * Rex Feany <rfeany@zumanetworks.com> - * on Jan/2002 for U-Boot. - * - * Clipped out all the non-1pass functions, cleaned up warnings, - * wrappers, etc. No major changes to the code. - * Please, he really means it when he said have a paper bag - * handy. We needed it ;). - * - */ - -/* - * Bugfixing by Kai-Uwe Bloem <kai-uwe.bloem@auerswald.de>, (C) Mar/2003 - * - * - overhaul of the memory management. Removed much of the "paper-bagging" - * in that part of the code, fixed several bugs, now frees memory when - * partition is changed. - * It's still ugly :-( - * - fixed a bug in jffs2_1pass_read_inode where the file length calculation - * was incorrect. Removed a bit of the paper-bagging as well. - * - removed double crc calculation for fragment headers in jffs2_private.h - * for speedup. - * - scan_empty rewritten in a more "standard" manner (non-paperbag, that is). - * - spinning wheel now spins depending on how much memory has been scanned - * - lots of small changes all over the place to "improve" readability. - * - implemented fragment sorting to ensure that the newest data is copied - * if there are multiple copies of fragments for a certain file offset. - * - * The fragment sorting feature must be enabled by CFG_JFFS2_SORT_FRAGMENTS. - * Sorting is done while adding fragments to the lists, which is more or less a - * bubble sort. This takes a lot of time, and is most probably not an issue if - * the boot filesystem is always mounted readonly. - * - * You should define it if the boot filesystem is mounted writable, and updates - * to the boot files are done by copying files to that filesystem. - * - * - * There's a big issue left: endianess is completely ignored in this code. Duh! - * - * - * You still should have paper bags at hand :-(. The code lacks more or less - * any comment, and is still arcane and difficult to read in places. As this - * might be incompatible with any new code from the jffs2 maintainers anyway, - * it should probably be dumped and replaced by something like jffs2reader! - */ - - -#include <common.h> -#include <config.h> -#include <malloc.h> -#include <linux/stat.h> -#include <linux/time.h> - -#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) - -#include <jffs2/jffs2.h> -#include <jffs2/jffs2_1pass.h> - -#include "jffs2_private.h" - - -#define NODE_CHUNK 1024 /* size of memory allocation chunk in b_nodes */ -#define SPIN_BLKSIZE 18 /* spin after having scanned 1<<BLKSIZE bytes */ - -/* Debugging switches */ -#undef DEBUG_DIRENTS /* print directory entry list after scan */ -#undef DEBUG_FRAGMENTS /* print fragment list after scan */ -#undef DEBUG /* enable debugging messages */ - - -#ifdef DEBUG -# define DEBUGF(fmt,args...) printf(fmt ,##args) -#else -# define DEBUGF(fmt,args...) -#endif - -/* keeps pointer to currentlu processed partition */ -static struct part_info *current_part; - -#if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) -#if defined(CFG_NAND_LEGACY) -#include <linux/mtd/nand_legacy.h> -#else -#include <nand.h> -#endif -/* - * Support for jffs2 on top of NAND-flash - * - * NAND memory isn't mapped in processor's address space, - * so data should be fetched from flash before - * being processed. This is exactly what functions declared - * here do. - * - */ - -#if defined(CFG_NAND_LEGACY) -/* this one defined in nand_legacy.c */ -int read_jffs2_nand(size_t start, size_t len, - size_t * retlen, u_char * buf, int nanddev); -#else -/* info for NAND chips, defined in drivers/nand/nand.c */ -extern nand_info_t nand_info[]; -#endif - -#define NAND_PAGE_SIZE 512 -#define NAND_PAGE_SHIFT 9 -#define NAND_PAGE_MASK (~(NAND_PAGE_SIZE-1)) - -#ifndef NAND_CACHE_PAGES -#define NAND_CACHE_PAGES 16 -#endif -#define NAND_CACHE_SIZE (NAND_CACHE_PAGES*NAND_PAGE_SIZE) - -static u8* nand_cache = NULL; -static u32 nand_cache_off = (u32)-1; - -static int read_nand_cached(u32 off, u32 size, u_char *buf) -{ - struct mtdids *id = current_part->dev->id; - u32 bytes_read = 0; -#if defined(CFG_NAND_LEGACY) - size_t retlen; -#else - ulong retlen; -#endif - int cpy_bytes; - - while (bytes_read < size) { - if ((off + bytes_read < nand_cache_off) || - (off + bytes_read >= nand_cache_off+NAND_CACHE_SIZE)) { - nand_cache_off = (off + bytes_read) & NAND_PAGE_MASK; - if (!nand_cache) { - /* This memory never gets freed but 'cause - it's a bootloader, nobody cares */ - nand_cache = malloc(NAND_CACHE_SIZE); - if (!nand_cache) { - printf("read_nand_cached: can't alloc cache size %d bytes\n", - NAND_CACHE_SIZE); - return -1; - } - } - -#if defined(CFG_NAND_LEGACY) - if (read_jffs2_nand(nand_cache_off, NAND_CACHE_SIZE, - &retlen, nand_cache, id->num) < 0 || - retlen != NAND_CACHE_SIZE) { - printf("read_nand_cached: error reading nand off %#x size %d bytes\n", - nand_cache_off, NAND_CACHE_SIZE); - return -1; - } -#else - retlen = NAND_CACHE_SIZE; - if (nand_read(&nand_info[id->num], nand_cache_off, - &retlen, nand_cache) != 0 || - retlen != NAND_CACHE_SIZE) { - printf("read_nand_cached: error reading nand off %#x size %d bytes\n", - nand_cache_off, NAND_CACHE_SIZE); - return -1; - } -#endif - } - cpy_bytes = nand_cache_off + NAND_CACHE_SIZE - (off + bytes_read); - if (cpy_bytes > size - bytes_read) - cpy_bytes = size - bytes_read; - memcpy(buf + bytes_read, - nand_cache + off + bytes_read - nand_cache_off, - cpy_bytes); - bytes_read += cpy_bytes; - } - return bytes_read; -} - -static void *get_fl_mem_nand(u32 off, u32 size, void *ext_buf) -{ - u_char *buf = ext_buf ? (u_char*)ext_buf : (u_char*)malloc(size); - - if (NULL == buf) { - printf("get_fl_mem_nand: can't alloc %d bytes\n", size); - return NULL; - } - if (read_nand_cached(off, size, buf) < 0) { - if (!ext_buf) - free(buf); - return NULL; - } - - return buf; -} - -static void *get_node_mem_nand(u32 off) -{ - struct jffs2_unknown_node node; - void *ret = NULL; - - if (NULL == get_fl_mem_nand(off, sizeof(node), &node)) - return NULL; - - if (!(ret = get_fl_mem_nand(off, node.magic == - JFFS2_MAGIC_BITMASK ? node.totlen : sizeof(node), - NULL))) { - printf("off = %#x magic %#x type %#x node.totlen = %d\n", - off, node.magic, node.nodetype, node.totlen); - } - return ret; -} - -static void put_fl_mem_nand(void *buf) -{ - free(buf); -} -#endif /* #if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) */ - - -#if (CONFIG_COMMANDS & CFG_CMD_FLASH) -/* - * Support for jffs2 on top of NOR-flash - * - * NOR flash memory is mapped in processor's address space, - * just return address. - */ -static inline void *get_fl_mem_nor(u32 off) -{ - u32 addr = off; - struct mtdids *id = current_part->dev->id; - - extern flash_info_t flash_info[]; - flash_info_t *flash = &flash_info[id->num]; - - addr += flash->start[0]; - return (void*)addr; -} - -static inline void *get_node_mem_nor(u32 off) -{ - return (void*)get_fl_mem_nor(off); -} -#endif /* #if (CONFIG_COMMANDS & CFG_CMD_FLASH) */ - - -/* - * Generic jffs2 raw memory and node read routines. - * - */ -static inline void *get_fl_mem(u32 off, u32 size, void *ext_buf) -{ - struct mtdids *id = current_part->dev->id; - -#if (CONFIG_COMMANDS & CFG_CMD_FLASH) - if (id->type == MTD_DEV_TYPE_NOR) - return get_fl_mem_nor(off); -#endif - -#if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) - if (id->type == MTD_DEV_TYPE_NAND) - return get_fl_mem_nand(off, size, ext_buf); -#endif - - printf("get_fl_mem: unknown device type, using raw offset!\n"); - return (void*)off; -} - -static inline void *get_node_mem(u32 off) -{ - struct mtdids *id = current_part->dev->id; - -#if (CONFIG_COMMANDS & CFG_CMD_FLASH) - if (id->type == MTD_DEV_TYPE_NOR) - return get_node_mem_nor(off); -#endif - -#if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) - if (id->type == MTD_DEV_TYPE_NAND) - return get_node_mem_nand(off); -#endif - - printf("get_node_mem: unknown device type, using raw offset!\n"); - return (void*)off; -} - -static inline void put_fl_mem(void *buf) -{ -#if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) - struct mtdids *id = current_part->dev->id; - - if (id->type == MTD_DEV_TYPE_NAND) - return put_fl_mem_nand(buf); -#endif -} - -/* Compression names */ -static char *compr_names[] = { - "NONE", - "ZERO", - "RTIME", - "RUBINMIPS", - "COPY", - "DYNRUBIN", - "ZLIB", -#if defined(CONFIG_JFFS2_LZO_LZARI) - "LZO", - "LZARI", -#endif -}; - -/* Spinning wheel */ -static char spinner[] = { '|', '/', '-', '\\' }; - -/* Memory management */ -struct mem_block { - u32 index; - struct mem_block *next; - struct b_node nodes[NODE_CHUNK]; -}; - - -static void -free_nodes(struct b_list *list) -{ - while (list->listMemBase != NULL) { - struct mem_block *next = list->listMemBase->next; - free( list->listMemBase ); - list->listMemBase = next; - } -} - -static struct b_node * -add_node(struct b_list *list) -{ - u32 index = 0; - struct mem_block *memBase; - struct b_node *b; - - memBase = list->listMemBase; - if (memBase != NULL) - index = memBase->index; - - if (memBase == NULL || index >= NODE_CHUNK) { - /* we need more space before we continue */ - memBase = mmalloc(sizeof(struct mem_block)); - if (memBase == NULL) { - putstr("add_node: malloc failed\n"); - return NULL; - } - memBase->next = list->listMemBase; - index = 0; - - } - /* now we have room to add it. */ - b = &memBase->nodes[index]; - index ++; - - memBase->index = index; - list->listMemBase = memBase; - list->listCount++; - return b; -} - -static struct b_node * -insert_node(struct b_list *list, u32 offset) -{ - struct b_node *new; -#ifdef CFG_JFFS2_SORT_FRAGMENTS - struct b_node *b, *prev; -#endif - - if (!(new = add_node(list))) { - putstr("add_node failed!\r\n"); - return NULL; - } - new->offset = offset; - -#ifdef CFG_JFFS2_SORT_FRAGMENTS - if (list->listTail != NULL && list->listCompare(new, list->listTail)) - prev = list->listTail; - else if (list->listLast != NULL && list->listCompare(new, list->listLast)) - prev = list->listLast; - else - prev = NULL; - - for (b = (prev ? prev->next : list->listHead); - b != NULL && list->listCompare(new, b); - prev = b, b = b->next) { - list->listLoops++; - } - if (b != NULL) - list->listLast = prev; - - if (b != NULL) { - new->next = b; - if (prev != NULL) - prev->next = new; - else - list->listHead = new; - } else -#endif - { - new->next = (struct b_node *) NULL; - if (list->listTail != NULL) { - list->listTail->next = new; - list->listTail = new; - } else { - list->listTail = list->listHead = new; - } - } - - return new; -} - -#ifdef CFG_JFFS2_SORT_FRAGMENTS -/* Sort data entries with the latest version last, so that if there - * is overlapping data the latest version will be used. - */ -static int compare_inodes(struct b_node *new, struct b_node *old) -{ - struct jffs2_raw_inode ojNew; - struct jffs2_raw_inode ojOld; - struct jffs2_raw_inode *jNew = - (struct jffs2_raw_inode *)get_fl_mem(new->offset, sizeof(ojNew), &ojNew); - struct jffs2_raw_inode *jOld = - (struct jffs2_raw_inode *)get_fl_mem(old->offset, sizeof(ojOld), &ojOld); - - return jNew->version > jOld->version; -} - -/* Sort directory entries so all entries in the same directory - * with the same name are grouped together, with the latest version - * last. This makes it easy to eliminate all but the latest version - * by marking the previous version dead by setting the inode to 0. - */ -static int compare_dirents(struct b_node *new, struct b_node *old) -{ - struct jffs2_raw_dirent ojNew; - struct jffs2_raw_dirent ojOld; - struct jffs2_raw_dirent *jNew = - (struct jffs2_raw_dirent *)get_fl_mem(new->offset, sizeof(ojNew), &ojNew); - struct jffs2_raw_dirent *jOld = - (struct jffs2_raw_dirent *)get_fl_mem(old->offset, sizeof(ojOld), &ojOld); - int cmp; - - /* ascending sort by pino */ - if (jNew->pino != jOld->pino) - return jNew->pino > jOld->pino; - - /* pino is the same, so use ascending sort by nsize, so - * we don't do strncmp unless we really must. - */ - if (jNew->nsize != jOld->nsize) - return jNew->nsize > jOld->nsize; - - /* length is also the same, so use ascending sort by name - */ - cmp = strncmp((char *)jNew->name, (char *)jOld->name, jNew->nsize); - if (cmp != 0) - return cmp > 0; - - /* we have duplicate names in this directory, so use ascending - * sort by version - */ - if (jNew->version > jOld->version) { - /* since jNew is newer, we know jOld is not valid, so - * mark it with inode 0 and it will not be used - */ - jOld->ino = 0; - return 1; - } - - return 0; -} -#endif - -static u32 -jffs2_scan_empty(u32 start_offset, struct part_info *part) -{ - char *max = (char *)(part->offset + part->size - sizeof(struct jffs2_raw_inode)); - char *offset = (char *)(part->offset + start_offset); - u32 off; - - while (offset < max && - *(u32*)get_fl_mem((u32)offset, sizeof(u32), &off) == 0xFFFFFFFF) { - offset += sizeof(u32); - /* return if spinning is due */ - if (((u32)offset & ((1 << SPIN_BLKSIZE)-1)) == 0) break; - } - - return (u32)offset - part->offset; -} - -void -jffs2_free_cache(struct part_info *part) -{ - struct b_lists *pL; - - if (part->jffs2_priv != NULL) { - pL = (struct b_lists *)part->jffs2_priv; - free_nodes(&pL->frag); - free_nodes(&pL->dir); - free(pL); - } -} - -static u32 -jffs_init_1pass_list(struct part_info *part) -{ - struct b_lists *pL; - - jffs2_free_cache(part); - - if (NULL != (part->jffs2_priv = malloc(sizeof(struct b_lists)))) { - pL = (struct b_lists *)part->jffs2_priv; - - memset(pL, 0, sizeof(*pL)); -#ifdef CFG_JFFS2_SORT_FRAGMENTS - pL->dir.listCompare = compare_dirents; - pL->frag.listCompare = compare_inodes; -#endif - } - return 0; -} - -/* find the inode from the slashless name given a parent */ -static long -jffs2_1pass_read_inode(struct b_lists *pL, u32 inode, char *dest) -{ - struct b_node *b; - struct jffs2_raw_inode *jNode; - u32 totalSize = 0; - u32 latestVersion = 0; - uchar *lDest; - uchar *src; - long ret; - int i; - u32 counter = 0; -#ifdef CFG_JFFS2_SORT_FRAGMENTS - /* Find file size before loading any data, so fragments that - * start past the end of file can be ignored. A fragment - * that is partially in the file is loaded, so extra data may - * be loaded up to the next 4K boundary above the file size. - * This shouldn't cause trouble when loading kernel images, so - * we will live with it. - */ - for (b = pL->frag.listHead; b != NULL; b = b->next) { - jNode = (struct jffs2_raw_inode *) get_fl_mem(b->offset, - sizeof(struct jffs2_raw_inode), NULL); - if ((inode == jNode->ino)) { - /* get actual file length from the newest node */ - if (jNode->version >= latestVersion) { - totalSize = jNode->isize; - latestVersion = jNode->version; - } - } - put_fl_mem(jNode); - } -#endif - - for (b = pL->frag.listHead; b != NULL; b = b->next) { - jNode = (struct jffs2_raw_inode *) get_node_mem(b->offset); - if ((inode == jNode->ino)) { - -#ifndef CFG_JFFS2_SORT_FRAGMENTS - /* get actual file length from the newest node */ - if (jNode->version >= latestVersion) { - totalSize = jNode->isize; - latestVersion = jNode->version; - } -#endif - - if(dest) { - src = ((uchar *) jNode) + sizeof(struct jffs2_raw_inode); - /* ignore data behind latest known EOF */ - if (jNode->offset > totalSize) { - put_fl_mem(jNode); - continue; - } - - lDest = (uchar *) (dest + jNode->offset); - switch (jNode->compr) { - case JFFS2_COMPR_NONE: - ret = (unsigned long) ldr_memcpy(lDest, src, jNode->dsize); - break; - case JFFS2_COMPR_ZERO: - ret = 0; - for (i = 0; i < jNode->dsize; i++) - *(lDest++) = 0; - break; - case JFFS2_COMPR_RTIME: - ret = 0; - rtime_decompress(src, lDest, jNode->csize, jNode->dsize); - break; - case JFFS2_COMPR_DYNRUBIN: - /* this is slow but it works */ - ret = 0; - dynrubin_decompress(src, lDest, jNode->csize, jNode->dsize); - break; - case JFFS2_COMPR_ZLIB: - ret = zlib_decompress(src, lDest, jNode->csize, jNode->dsize); - break; -#if defined(CONFIG_JFFS2_LZO_LZARI) - case JFFS2_COMPR_LZO: - ret = lzo_decompress(src, lDest, jNode->csize, jNode->dsize); - break; - case JFFS2_COMPR_LZARI: - ret = lzari_decompress(src, lDest, jNode->csize, jNode->dsize); - break; -#endif - default: - /* unknown */ - putLabeledWord("UNKOWN COMPRESSION METHOD = ", jNode->compr); - put_fl_mem(jNode); - return -1; - break; - } - } - - } - counter++; - put_fl_mem(jNode); - } - - return totalSize; -} - -/* find the inode from the slashless name given a parent */ -static u32 -jffs2_1pass_find_inode(struct b_lists * pL, const char *name, u32 pino) -{ - struct b_node *b; - struct jffs2_raw_dirent *jDir; - int len; - u32 counter; - u32 version = 0; - u32 inode = 0; - - /* name is assumed slash free */ - len = strlen(name); - - counter = 0; - /* we need to search all and return the inode with the highest version */ - for(b = pL->dir.listHead; b; b = b->next, counter++) { - jDir = (struct jffs2_raw_dirent *) get_node_mem(b->offset); - if ((pino == jDir->pino) && (len == jDir->nsize) && - (jDir->ino) && /* 0 for unlink */ - (!strncmp((char *)jDir->name, name, len))) { /* a match */ - if (jDir->version < version) { - put_fl_mem(jDir); - continue; - } - - if (jDir->version == version && inode != 0) { - /* I'm pretty sure this isn't legal */ - putstr(" ** ERROR ** "); - putnstr(jDir->name, jDir->nsize); - putLabeledWord(" has dup version =", version); - } - inode = jDir->ino; - version = jDir->version; - } - put_fl_mem(jDir); - } - return inode; -} - -char *mkmodestr(unsigned long mode, char *str) -{ - static const char *l = "xwr"; - int mask = 1, i; - char c; - - switch (mode & S_IFMT) { - case S_IFDIR: str[0] = 'd'; break; - case S_IFBLK: str[0] = 'b'; break; - case S_IFCHR: str[0] = 'c'; break; - case S_IFIFO: str[0] = 'f'; break; - case S_IFLNK: str[0] = 'l'; break; - case S_IFSOCK: str[0] = 's'; break; - case S_IFREG: str[0] = '-'; break; - default: str[0] = '?'; - } - - for(i = 0; i < 9; i++) { - c = l[i%3]; - str[9-i] = (mode & mask)?c:'-'; - mask = mask<<1; - } - - if(mode & S_ISUID) str[3] = (mode & S_IXUSR)?'s':'S'; - if(mode & S_ISGID) str[6] = (mode & S_IXGRP)?'s':'S'; - if(mode & S_ISVTX) str[9] = (mode & S_IXOTH)?'t':'T'; - str[10] = '\0'; - return str; -} - -static inline void dump_stat(struct stat *st, const char *name) -{ - char str[20]; - char s[64], *p; - - if (st->st_mtime == (time_t)(-1)) /* some ctimes really hate -1 */ - st->st_mtime = 1; - - ctime_r((time_t *)&st->st_mtime, s/*,64*/); /* newlib ctime doesn't have buflen */ - - if ((p = strchr(s,'\n')) != NULL) *p = '\0'; - if ((p = strchr(s,'\r')) != NULL) *p = '\0'; - -/* - printf("%6lo %s %8ld %s %s\n", st->st_mode, mkmodestr(st->st_mode, str), - st->st_size, s, name); -*/ - - printf(" %s %8ld %s %s", mkmodestr(st->st_mode,str), st->st_size, s, name); -} - -static inline u32 dump_inode(struct b_lists * pL, struct jffs2_raw_dirent *d, struct jffs2_raw_inode *i) -{ - char fname[256]; - struct stat st; - - if(!d || !i) return -1; - - strncpy(fname, (char *)d->name, d->nsize); - fname[d->nsize] = '\0'; - - memset(&st,0,sizeof(st)); - - st.st_mtime = i->mtime; - st.st_mode = i->mode; - st.st_ino = i->ino; - - /* neither dsize nor isize help us.. do it the long way */ - st.st_size = jffs2_1pass_read_inode(pL, i->ino, NULL); - - dump_stat(&st, fname); - - if (d->type == DT_LNK) { - unsigned char *src = (unsigned char *) (&i[1]); - putstr(" -> "); - putnstr(src, (int)i->dsize); - } - - putstr("\r\n"); - - return 0; -} - -/* list inodes with the given pino */ -static u32 -jffs2_1pass_list_inodes(struct b_lists * pL, u32 pino) -{ - struct b_node *b; - struct jffs2_raw_dirent *jDir; - - for (b = pL->dir.listHead; b; b = b->next) { - jDir = (struct jffs2_raw_dirent *) get_node_mem(b->offset); - if ((pino == jDir->pino) && (jDir->ino)) { /* ino=0 -> unlink */ - u32 i_version = 0; - struct jffs2_raw_inode ojNode; - struct jffs2_raw_inode *jNode, *i = NULL; - struct b_node *b2 = pL->frag.listHead; - - while (b2) { - jNode = (struct jffs2_raw_inode *) - get_fl_mem(b2->offset, sizeof(ojNode), &ojNode); - if (jNode->ino == jDir->ino && jNode->version >= i_version) { - if (i) - put_fl_mem(i); - - if (jDir->type == DT_LNK) - i = get_node_mem(b2->offset); - else - i = get_fl_mem(b2->offset, sizeof(*i), NULL); - } - b2 = b2->next; - } - - dump_inode(pL, jDir, i); - put_fl_mem(i); - } - put_fl_mem(jDir); - } - return pino; -} - -static u32 -jffs2_1pass_search_inode(struct b_lists * pL, const char *fname, u32 pino) -{ - int i; - char tmp[256]; - char working_tmp[256]; - char *c; - - /* discard any leading slash */ - i = 0; - while (fname[i] == '/') - i++; - strcpy(tmp, &fname[i]); - - while ((c = (char *) strchr(tmp, '/'))) /* we are still dired searching */ - { - strncpy(working_tmp, tmp, c - tmp); - working_tmp[c - tmp] = '\0'; - for (i = 0; i < strlen(c) - 1; i++) - tmp[i] = c[i + 1]; - tmp[i] = '\0'; - - if (!(pino = jffs2_1pass_find_inode(pL, working_tmp, pino))) { - putstr("find_inode failed for name="); - putstr(working_tmp); - putstr("\r\n"); - return 0; - } - } - /* this is for the bare filename, directories have already been mapped */ - if (!(pino = jffs2_1pass_find_inode(pL, tmp, pino))) { - putstr("find_inode failed for name="); - putstr(tmp); - putstr("\r\n"); - return 0; - } - return pino; - -} - -static u32 -jffs2_1pass_resolve_inode(struct b_lists * pL, u32 ino) -{ - struct b_node *b; - struct b_node *b2; - struct jffs2_raw_dirent *jDir; - struct jffs2_raw_inode *jNode; - u8 jDirFoundType = 0; - u32 jDirFoundIno = 0; - u32 jDirFoundPino = 0; - char tmp[256]; - u32 version = 0; - u32 pino; - unsigned char *src; - - /* we need to search all and return the inode with the highest version */ - for(b = pL->dir.listHead; b; b = b->next) { - jDir = (struct jffs2_raw_dirent *) get_node_mem(b->offset); - if (ino == jDir->ino) { - if (jDir->version < version) { - put_fl_mem(jDir); - continue; - } - - if (jDir->version == version && jDirFoundType) { - /* I'm pretty sure this isn't legal */ - putstr(" ** ERROR ** "); - putnstr(jDir->name, jDir->nsize); - putLabeledWord(" has dup version (resolve) = ", - version); - } - - jDirFoundType = jDir->type; - jDirFoundIno = jDir->ino; - jDirFoundPino = jDir->pino; - version = jDir->version; - } - put_fl_mem(jDir); - } - /* now we found the right entry again. (shoulda returned inode*) */ - if (jDirFoundType != DT_LNK) - return jDirFoundIno; - - /* it's a soft link so we follow it again. */ - b2 = pL->frag.listHead; - while (b2) { - jNode = (struct jffs2_raw_inode *) get_node_mem(b2->offset); - if (jNode->ino == jDirFoundIno) { - src = (unsigned char *)jNode + sizeof(struct jffs2_raw_inode); - - strncpy(tmp, (char *)src, jNode->dsize); - tmp[jNode->dsize] = '\0'; - put_fl_mem(jNode); - break; - } - b2 = b2->next; - put_fl_mem(jNode); - } - /* ok so the name of the new file to find is in tmp */ - /* if it starts with a slash it is root based else shared dirs */ - if (tmp[0] == '/') - pino = 1; - else - pino = jDirFoundPino; - - return jffs2_1pass_search_inode(pL, tmp, pino); -} - -static u32 -jffs2_1pass_search_list_inodes(struct b_lists * pL, const char *fname, u32 pino) -{ - int i; - char tmp[256]; - char working_tmp[256]; - char *c; - - /* discard any leading slash */ - i = 0; - while (fname[i] == '/') - i++; - strcpy(tmp, &fname[i]); - working_tmp[0] = '\0'; - while ((c = (char *) strchr(tmp, '/'))) /* we are still dired searching */ - { - strncpy(working_tmp, tmp, c - tmp); - working_tmp[c - tmp] = '\0'; - for (i = 0; i < strlen(c) - 1; i++) - tmp[i] = c[i + 1]; - tmp[i] = '\0'; - /* only a failure if we arent looking at top level */ - if (!(pino = jffs2_1pass_find_inode(pL, working_tmp, pino)) && - (working_tmp[0])) { - putstr("find_inode failed for name="); - putstr(working_tmp); - putstr("\r\n"); - return 0; - } - } - - if (tmp[0] && !(pino = jffs2_1pass_find_inode(pL, tmp, pino))) { - putstr("find_inode failed for name="); - putstr(tmp); - putstr("\r\n"); - return 0; - } - /* this is for the bare filename, directories have already been mapped */ - if (!(pino = jffs2_1pass_list_inodes(pL, pino))) { - putstr("find_inode failed for name="); - putstr(tmp); - putstr("\r\n"); - return 0; - } - return pino; - -} - -unsigned char -jffs2_1pass_rescan_needed(struct part_info *part) -{ - struct b_node *b; - struct jffs2_unknown_node onode; - struct jffs2_unknown_node *node; - struct b_lists *pL = (struct b_lists *)part->jffs2_priv; - - if (part->jffs2_priv == 0){ - DEBUGF ("rescan: First time in use\n"); - return 1; - } - - /* if we have no list, we need to rescan */ - if (pL->frag.listCount == 0) { - DEBUGF ("rescan: fraglist zero\n"); - return 1; - } - - /* but suppose someone reflashed a partition at the same offset... */ - b = pL->dir.listHead; - while (b) { - node = (struct jffs2_unknown_node *) get_fl_mem(b->offset, - sizeof(onode), &onode); - if (node->nodetype != JFFS2_NODETYPE_DIRENT) { - DEBUGF ("rescan: fs changed beneath me? (%lx)\n", - (unsigned long) b->offset); - return 1; - } - b = b->next; - } - return 0; -} - -#ifdef DEBUG_FRAGMENTS -static void -dump_fragments(struct b_lists *pL) -{ - struct b_node *b; - struct jffs2_raw_inode ojNode; - struct jffs2_raw_inode *jNode; - - putstr("\r\n\r\n******The fragment Entries******\r\n"); - b = pL->frag.listHead; - while (b) { - jNode = (struct jffs2_raw_inode *) get_fl_mem(b->offset, - sizeof(ojNode), &ojNode); - putLabeledWord("\r\n\tbuild_list: FLASH_OFFSET = ", b->offset); - putLabeledWord("\tbuild_list: totlen = ", jNode->totlen); - putLabeledWord("\tbuild_list: inode = ", jNode->ino); - putLabeledWord("\tbuild_list: version = ", jNode->version); - putLabeledWord("\tbuild_list: isize = ", jNode->isize); - putLabeledWord("\tbuild_list: atime = ", jNode->atime); - putLabeledWord("\tbuild_list: offset = ", jNode->offset); - putLabeledWord("\tbuild_list: csize = ", jNode->csize); - putLabeledWord("\tbuild_list: dsize = ", jNode->dsize); - putLabeledWord("\tbuild_list: compr = ", jNode->compr); - putLabeledWord("\tbuild_list: usercompr = ", jNode->usercompr); - putLabeledWord("\tbuild_list: flags = ", jNode->flags); - putLabeledWord("\tbuild_list: offset = ", b->offset); /* FIXME: ? [RS] */ - b = b->next; - } -} -#endif - -#ifdef DEBUG_DIRENTS -static void -dump_dirents(struct b_lists *pL) -{ - struct b_node *b; - struct jffs2_raw_dirent *jDir; - - putstr("\r\n\r\n******The directory Entries******\r\n"); - b = pL->dir.listHead; - while (b) { - jDir = (struct jffs2_raw_dirent *) get_node_mem(b->offset); - putstr("\r\n"); - putnstr(jDir->name, jDir->nsize); - putLabeledWord("\r\n\tbuild_list: magic = ", jDir->magic); - putLabeledWord("\tbuild_list: nodetype = ", jDir->nodetype); - putLabeledWord("\tbuild_list: hdr_crc = ", jDir->hdr_crc); - putLabeledWord("\tbuild_list: pino = ", jDir->pino); - putLabeledWord("\tbuild_list: version = ", jDir->version); - putLabeledWord("\tbuild_list: ino = ", jDir->ino); - putLabeledWord("\tbuild_list: mctime = ", jDir->mctime); - putLabeledWord("\tbuild_list: nsize = ", jDir->nsize); - putLabeledWord("\tbuild_list: type = ", jDir->type); - putLabeledWord("\tbuild_list: node_crc = ", jDir->node_crc); - putLabeledWord("\tbuild_list: name_crc = ", jDir->name_crc); - putLabeledWord("\tbuild_list: offset = ", b->offset); /* FIXME: ? [RS] */ - b = b->next; - put_fl_mem(jDir); - } -} -#endif - -static u32 -jffs2_1pass_build_lists(struct part_info * part) -{ - struct b_lists *pL; - struct jffs2_unknown_node *node; - u32 offset, oldoffset = 0; - u32 max = part->size - sizeof(struct jffs2_raw_inode); - u32 counter = 0; - u32 counter4 = 0; - u32 counterF = 0; - u32 counterN = 0; - - /* turn off the lcd. Refreshing the lcd adds 50% overhead to the */ - /* jffs2 list building enterprise nope. in newer versions the overhead is */ - /* only about 5 %. not enough to inconvenience people for. */ - /* lcd_off(); */ - - /* if we are building a list we need to refresh the cache. */ - jffs_init_1pass_list(part); - pL = (struct b_lists *)part->jffs2_priv; - offset = 0; - puts ("Scanning JFFS2 FS: "); - - /* start at the beginning of the partition */ - while (offset < max) { - if ((oldoffset >> SPIN_BLKSIZE) != (offset >> SPIN_BLKSIZE)) { - printf("\b\b%c ", spinner[counter++ % sizeof(spinner)]); - oldoffset = offset; - } - - node = (struct jffs2_unknown_node *) get_node_mem((u32)part->offset + offset); - if (node->magic == JFFS2_MAGIC_BITMASK && hdr_crc(node)) { - /* if its a fragment add it */ - if (node->nodetype == JFFS2_NODETYPE_INODE && - inode_crc((struct jffs2_raw_inode *) node) && - data_crc((struct jffs2_raw_inode *) node)) { - if (insert_node(&pL->frag, (u32) part->offset + - offset) == NULL) { - put_fl_mem(node); - return 0; - } - } else if (node->nodetype == JFFS2_NODETYPE_DIRENT && - dirent_crc((struct jffs2_raw_dirent *) node) && - dirent_name_crc((struct jffs2_raw_dirent *) node)) { - if (! (counterN%100)) - puts ("\b\b. "); - if (insert_node(&pL->dir, (u32) part->offset + - offset) == NULL) { - put_fl_mem(node); - return 0; - } - counterN++; - } else if (node->nodetype == JFFS2_NODETYPE_CLEANMARKER) { - if (node->totlen != sizeof(struct jffs2_unknown_node)) - printf("OOPS Cleanmarker has bad size " - "%d != %d\n", node->totlen, - sizeof(struct jffs2_unknown_node)); - } else if (node->nodetype == JFFS2_NODETYPE_PADDING) { - if (node->totlen < sizeof(struct jffs2_unknown_node)) - printf("OOPS Padding has bad size " - "%d < %d\n", node->totlen, - sizeof(struct jffs2_unknown_node)); - } else { - printf("Unknown node type: %x len %d " - "offset 0x%x\n", node->nodetype, - node->totlen, offset); - } - offset += ((node->totlen + 3) & ~3); - counterF++; - } else if (node->magic == JFFS2_EMPTY_BITMASK && - node->nodetype == JFFS2_EMPTY_BITMASK) { - offset = jffs2_scan_empty(offset, part); - } else { /* if we know nothing, we just step and look. */ - offset += 4; - counter4++; - } -/* printf("unknown node magic %4.4x %4.4x @ %lx\n", node->magic, node->nodetype, (unsigned long)node); */ - put_fl_mem(node); - } - - putstr("\b\b done.\r\n"); /* close off the dots */ - /* turn the lcd back on. */ - /* splash(); */ - - -#ifdef DEBUG_DIRENTS - dump_dirents(pL); -#endif - -#ifdef DEBUG_FRAGMENTS - dump_fragments(pL); -#endif - - /* give visual feedback that we are done scanning the flash */ - led_blink(0x0, 0x0, 0x1, 0x1); /* off, forever, on 100ms, off 100ms */ - return 1; -} - - -static u32 -jffs2_1pass_fill_info(struct b_lists * pL, struct b_jffs2_info * piL) -{ - struct b_node *b; - struct jffs2_raw_inode ojNode; - struct jffs2_raw_inode *jNode; - int i; - - for (i = 0; i < JFFS2_NUM_COMPR; i++) { - piL->compr_info[i].num_frags = 0; - piL->compr_info[i].compr_sum = 0; - piL->compr_info[i].decompr_sum = 0; - } - - b = pL->frag.listHead; - while (b) { - jNode = (struct jffs2_raw_inode *) get_fl_mem(b->offset, - sizeof(ojNode), &ojNode); - if (jNode->compr < JFFS2_NUM_COMPR) { - piL->compr_info[jNode->compr].num_frags++; - piL->compr_info[jNode->compr].compr_sum += jNode->csize; - piL->compr_info[jNode->compr].decompr_sum += jNode->dsize; - } - b = b->next; - } - return 0; -} - - -static struct b_lists * -jffs2_get_list(struct part_info * part, const char *who) -{ - /* copy requested part_info struct pointer to global location */ - current_part = part; - - if (jffs2_1pass_rescan_needed(part)) { - if (!jffs2_1pass_build_lists(part)) { - printf("%s: Failed to scan JFFSv2 file structure\n", who); - return NULL; - } - } - return (struct b_lists *)part->jffs2_priv; -} - - -/* Print directory / file contents */ -u32 -jffs2_1pass_ls(struct part_info * part, const char *fname) -{ - struct b_lists *pl; - long ret = 1; - u32 inode; - - if (! (pl = jffs2_get_list(part, "ls"))) - return 0; - - if (! (inode = jffs2_1pass_search_list_inodes(pl, fname, 1))) { - putstr("ls: Failed to scan jffs2 file structure\r\n"); - return 0; - } - - - - return ret; -} - - -/* Load a file from flash into memory. fname can be a full path */ -u32 -jffs2_1pass_load(char *dest, struct part_info * part, const char *fname) -{ - - struct b_lists *pl; - long ret = 1; - u32 inode; - - if (! (pl = jffs2_get_list(part, "load"))) - return 0; - - if (! (inode = jffs2_1pass_search_inode(pl, fname, 1))) { - putstr("load: Failed to find inode\r\n"); - return 0; - } - - /* Resolve symlinks */ - if (! (inode = jffs2_1pass_resolve_inode(pl, inode))) { - putstr("load: Failed to resolve inode structure\r\n"); - return 0; - } - - if ((ret = jffs2_1pass_read_inode(pl, inode, dest)) < 0) { - putstr("load: Failed to read inode\r\n"); - return 0; - } - - DEBUGF ("load: loaded '%s' to 0x%lx (%ld bytes)\n", fname, - (unsigned long) dest, ret); - return ret; -} - -/* Return information about the fs on this partition */ -u32 -jffs2_1pass_info(struct part_info * part) -{ - struct b_jffs2_info info; - struct b_lists *pl; - int i; - - if (! (pl = jffs2_get_list(part, "info"))) - return 0; - - jffs2_1pass_fill_info(pl, &info); - for (i = 0; i < JFFS2_NUM_COMPR; i++) { - printf ("Compression: %s\n" - "\tfrag count: %d\n" - "\tcompressed sum: %d\n" - "\tuncompressed sum: %d\n", - compr_names[i], - info.compr_info[i].num_frags, - info.compr_info[i].compr_sum, - info.compr_info[i].decompr_sum); - } - return 1; -} - -#endif /* CFG_CMD_JFFS2 */ diff --git a/fs/jffs2/jffs2_nand_1pass.c b/fs/jffs2/jffs2_nand_1pass.c deleted file mode 100644 index 917a1b4814..0000000000 --- a/fs/jffs2/jffs2_nand_1pass.c +++ /dev/null @@ -1,966 +0,0 @@ -#include <common.h> - -#if !defined(CFG_NAND_LEGACY) && (CONFIG_COMMANDS & CFG_CMD_JFFS2) - -#include <malloc.h> -#include <linux/stat.h> -#include <linux/time.h> - -#include <jffs2/jffs2.h> -#include <jffs2/jffs2_1pass.h> -#include <nand.h> - -#include "jffs2_nand_private.h" - -#define NODE_CHUNK 1024 /* size of memory allocation chunk in b_nodes */ - -/* Debugging switches */ -#undef DEBUG_DIRENTS /* print directory entry list after scan */ -#undef DEBUG_FRAGMENTS /* print fragment list after scan */ -#undef DEBUG /* enable debugging messages */ - -#ifdef DEBUG -# define DEBUGF(fmt,args...) printf(fmt ,##args) -#else -# define DEBUGF(fmt,args...) -#endif - -static nand_info_t *nand; - -/* Compression names */ -static char *compr_names[] = { - "NONE", - "ZERO", - "RTIME", - "RUBINMIPS", - "COPY", - "DYNRUBIN", - "ZLIB", -#if defined(CONFIG_JFFS2_LZO_LZARI) - "LZO", - "LZARI", -#endif -}; - -/* Spinning wheel */ -static char spinner[] = { '|', '/', '-', '\\' }; - -/* Memory management */ -struct mem_block { - unsigned index; - struct mem_block *next; - char nodes[0]; -}; - -static void -free_nodes(struct b_list *list) -{ - while (list->listMemBase != NULL) { - struct mem_block *next = list->listMemBase->next; - free(list->listMemBase); - list->listMemBase = next; - } -} - -static struct b_node * -add_node(struct b_list *list, int size) -{ - u32 index = 0; - struct mem_block *memBase; - struct b_node *b; - - memBase = list->listMemBase; - if (memBase != NULL) - index = memBase->index; - - if (memBase == NULL || index >= NODE_CHUNK) { - /* we need more space before we continue */ - memBase = mmalloc(sizeof(struct mem_block) + NODE_CHUNK * size); - if (memBase == NULL) { - putstr("add_node: malloc failed\n"); - return NULL; - } - memBase->next = list->listMemBase; - index = 0; - } - /* now we have room to add it. */ - b = (struct b_node *)&memBase->nodes[size * index]; - index ++; - - memBase->index = index; - list->listMemBase = memBase; - list->listCount++; - return b; -} - -static struct b_node * -insert_node(struct b_list *list, struct b_node *new) -{ -#ifdef CFG_JFFS2_SORT_FRAGMENTS - struct b_node *b, *prev; - - if (list->listTail != NULL && list->listCompare(new, list->listTail)) - prev = list->listTail; - else if (list->listLast != NULL && list->listCompare(new, list->listLast)) - prev = list->listLast; - else - prev = NULL; - - for (b = (prev ? prev->next : list->listHead); - b != NULL && list->listCompare(new, b); - prev = b, b = b->next) { - list->listLoops++; - } - if (b != NULL) - list->listLast = prev; - - if (b != NULL) { - new->next = b; - if (prev != NULL) - prev->next = new; - else - list->listHead = new; - } else -#endif - { - new->next = (struct b_node *) NULL; - if (list->listTail != NULL) { - list->listTail->next = new; - list->listTail = new; - } else { - list->listTail = list->listHead = new; - } - } - - return new; -} - -static struct b_node * -insert_inode(struct b_list *list, struct jffs2_raw_inode *node, u32 offset) -{ - struct b_inode *new; - - if (!(new = (struct b_inode *)add_node(list, sizeof(struct b_inode)))) { - putstr("add_node failed!\r\n"); - return NULL; - } - new->offset = offset; - new->version = node->version; - new->ino = node->ino; - new->isize = node->isize; - new->csize = node->csize; - - return insert_node(list, (struct b_node *)new); -} - -static struct b_node * -insert_dirent(struct b_list *list, struct jffs2_raw_dirent *node, u32 offset) -{ - struct b_dirent *new; - - if (!(new = (struct b_dirent *)add_node(list, sizeof(struct b_dirent)))) { - putstr("add_node failed!\r\n"); - return NULL; - } - new->offset = offset; - new->version = node->version; - new->pino = node->pino; - new->ino = node->ino; - new->nhash = full_name_hash(node->name, node->nsize); - new->nsize = node->nsize; - new->type = node->type; - - return insert_node(list, (struct b_node *)new); -} - -#ifdef CFG_JFFS2_SORT_FRAGMENTS -/* Sort data entries with the latest version last, so that if there - * is overlapping data the latest version will be used. - */ -static int compare_inodes(struct b_node *new, struct b_node *old) -{ - struct jffs2_raw_inode ojNew; - struct jffs2_raw_inode ojOld; - struct jffs2_raw_inode *jNew = - (struct jffs2_raw_inode *)get_fl_mem(new->offset, sizeof(ojNew), &ojNew); - struct jffs2_raw_inode *jOld = - (struct jffs2_raw_inode *)get_fl_mem(old->offset, sizeof(ojOld), &ojOld); - - return jNew->version > jOld->version; -} - -/* Sort directory entries so all entries in the same directory - * with the same name are grouped together, with the latest version - * last. This makes it easy to eliminate all but the latest version - * by marking the previous version dead by setting the inode to 0. - */ -static int compare_dirents(struct b_node *new, struct b_node *old) -{ - struct jffs2_raw_dirent ojNew; - struct jffs2_raw_dirent ojOld; - struct jffs2_raw_dirent *jNew = - (struct jffs2_raw_dirent *)get_fl_mem(new->offset, sizeof(ojNew), &ojNew); - struct jffs2_raw_dirent *jOld = - (struct jffs2_raw_dirent *)get_fl_mem(old->offset, sizeof(ojOld), &ojOld); - int cmp; - - /* ascending sort by pino */ - if (jNew->pino != jOld->pino) - return jNew->pino > jOld->pino; - - /* pino is the same, so use ascending sort by nsize, so - * we don't do strncmp unless we really must. - */ - if (jNew->nsize != jOld->nsize) - return jNew->nsize > jOld->nsize; - - /* length is also the same, so use ascending sort by name - */ - cmp = strncmp(jNew->name, jOld->name, jNew->nsize); - if (cmp != 0) - return cmp > 0; - - /* we have duplicate names in this directory, so use ascending - * sort by version - */ - if (jNew->version > jOld->version) { - /* since jNew is newer, we know jOld is not valid, so - * mark it with inode 0 and it will not be used - */ - jOld->ino = 0; - return 1; - } - - return 0; -} -#endif - -static u32 -jffs_init_1pass_list(struct part_info *part) -{ - struct b_lists *pL; - - if (part->jffs2_priv != NULL) { - pL = (struct b_lists *)part->jffs2_priv; - free_nodes(&pL->frag); - free_nodes(&pL->dir); - free(pL); - } - if (NULL != (part->jffs2_priv = malloc(sizeof(struct b_lists)))) { - pL = (struct b_lists *)part->jffs2_priv; - - memset(pL, 0, sizeof(*pL)); -#ifdef CFG_JFFS2_SORT_FRAGMENTS - pL->dir.listCompare = compare_dirents; - pL->frag.listCompare = compare_inodes; -#endif - } - return 0; -} - -/* find the inode from the slashless name given a parent */ -static long -jffs2_1pass_read_inode(struct b_lists *pL, u32 ino, char *dest, - struct stat *stat) -{ - struct b_inode *jNode; - u32 totalSize = 0; - u32 latestVersion = 0; - long ret; - -#ifdef CFG_JFFS2_SORT_FRAGMENTS - /* Find file size before loading any data, so fragments that - * start past the end of file can be ignored. A fragment - * that is partially in the file is loaded, so extra data may - * be loaded up to the next 4K boundary above the file size. - * This shouldn't cause trouble when loading kernel images, so - * we will live with it. - */ - for (jNode = (struct b_inode *)pL->frag.listHead; jNode; jNode = jNode->next) { - if ((ino == jNode->ino)) { - /* get actual file length from the newest node */ - if (jNode->version >= latestVersion) { - totalSize = jNode->isize; - latestVersion = jNode->version; - } - } - } -#endif - - for (jNode = (struct b_inode *)pL->frag.listHead; jNode; jNode = jNode->next) { - if ((ino != jNode->ino)) - continue; -#ifndef CFG_JFFS2_SORT_FRAGMENTS - /* get actual file length from the newest node */ - if (jNode->version >= latestVersion) { - totalSize = jNode->isize; - latestVersion = jNode->version; - } -#endif - if (dest || stat) { - char *src, *dst; - char data[4096 + sizeof(struct jffs2_raw_inode)]; - struct jffs2_raw_inode *inode; - size_t len; - - inode = (struct jffs2_raw_inode *)&data; - len = sizeof(struct jffs2_raw_inode); - if (dest) - len += jNode->csize; - nand_read(nand, jNode->offset, &len, inode); - /* ignore data behind latest known EOF */ - if (inode->offset > totalSize) - continue; - - if (stat) { - stat->st_mtime = inode->mtime; - stat->st_mode = inode->mode; - stat->st_ino = inode->ino; - stat->st_size = totalSize; - } - - if (!dest) - continue; - - src = ((char *) inode) + sizeof(struct jffs2_raw_inode); - dst = (char *) (dest + inode->offset); - - switch (inode->compr) { - case JFFS2_COMPR_NONE: - ret = 0; - memcpy(dst, src, inode->dsize); - break; - case JFFS2_COMPR_ZERO: - ret = 0; - memset(dst, 0, inode->dsize); - break; - case JFFS2_COMPR_RTIME: - ret = 0; - rtime_decompress(src, dst, inode->csize, inode->dsize); - break; - case JFFS2_COMPR_DYNRUBIN: - /* this is slow but it works */ - ret = 0; - dynrubin_decompress(src, dst, inode->csize, inode->dsize); - break; - case JFFS2_COMPR_ZLIB: - ret = zlib_decompress(src, dst, inode->csize, inode->dsize); - break; -#if defined(CONFIG_JFFS2_LZO_LZARI) - case JFFS2_COMPR_LZO: - ret = lzo_decompress(src, dst, inode->csize, inode->dsize); - break; - case JFFS2_COMPR_LZARI: - ret = lzari_decompress(src, dst, inode->csize, inode->dsize); - break; -#endif - default: - /* unknown */ - putLabeledWord("UNKOWN COMPRESSION METHOD = ", inode->compr); - return -1; - } - } - } - - return totalSize; -} - -/* find the inode from the slashless name given a parent */ -static u32 -jffs2_1pass_find_inode(struct b_lists * pL, const char *name, u32 pino) -{ - struct b_dirent *jDir; - int len = strlen(name); /* name is assumed slash free */ - unsigned int nhash = full_name_hash(name, len); - u32 version = 0; - u32 inode = 0; - - /* we need to search all and return the inode with the highest version */ - for (jDir = (struct b_dirent *)pL->dir.listHead; jDir; jDir = jDir->next) { - if ((pino == jDir->pino) && (jDir->ino) && /* 0 for unlink */ - (len == jDir->nsize) && (nhash == jDir->nhash)) { - /* TODO: compare name */ - if (jDir->version < version) - continue; - - if (jDir->version == version && inode != 0) { - /* I'm pretty sure this isn't legal */ - putstr(" ** ERROR ** "); -/* putnstr(jDir->name, jDir->nsize); */ -/* putLabeledWord(" has dup version =", version); */ - } - inode = jDir->ino; - version = jDir->version; - } - } - return inode; -} - -static inline void dump_stat(struct stat *st, const char *name) -{ - char str[20]; - char s[64], *p; - - if (st->st_mtime == (time_t)(-1)) /* some ctimes really hate -1 */ - st->st_mtime = 1; - - ctime_r(&st->st_mtime, s/*,64*/); /* newlib ctime doesn't have buflen */ - - if ((p = strchr(s,'\n')) != NULL) *p = '\0'; - if ((p = strchr(s,'\r')) != NULL) *p = '\0'; - -/* - printf("%6lo %s %8ld %s %s\n", st->st_mode, mkmodestr(st->st_mode, str), - st->st_size, s, name); -*/ - - printf(" %s %8ld %s %s", mkmodestr(st->st_mode,str), st->st_size, s, name); -} - -static inline int -dump_inode(struct b_lists *pL, struct b_dirent *d, struct b_inode *i) -{ - char fname[JFFS2_MAX_NAME_LEN + 1]; - struct stat st; - size_t len; - - if(!d || !i) return -1; - len = d->nsize; - nand_read(nand, d->offset + sizeof(struct jffs2_raw_dirent), - &len, &fname); - fname[d->nsize] = '\0'; - - memset(&st, 0, sizeof(st)); - - jffs2_1pass_read_inode(pL, i->ino, NULL, &st); - - dump_stat(&st, fname); -/* FIXME - if (d->type == DT_LNK) { - unsigned char *src = (unsigned char *) (&i[1]); - putstr(" -> "); - putnstr(src, (int)i->dsize); - } -*/ - putstr("\r\n"); - - return 0; -} - -/* list inodes with the given pino */ -static u32 -jffs2_1pass_list_inodes(struct b_lists * pL, u32 pino) -{ - struct b_dirent *jDir; - u32 i_version = 0; - - for (jDir = (struct b_dirent *)pL->dir.listHead; jDir; jDir = jDir->next) { - if ((pino == jDir->pino) && (jDir->ino)) { /* ino=0 -> unlink */ - struct b_inode *jNode = (struct b_inode *)pL->frag.listHead; - struct b_inode *i = NULL; - - while (jNode) { - if (jNode->ino == jDir->ino && jNode->version >= i_version) { - i_version = jNode->version; - i = jNode; - } - jNode = jNode->next; - } - dump_inode(pL, jDir, i); - } - } - return pino; -} - -static u32 -jffs2_1pass_search_inode(struct b_lists * pL, const char *fname, u32 pino) -{ - int i; - char tmp[256]; - char working_tmp[256]; - char *c; - - /* discard any leading slash */ - i = 0; - while (fname[i] == '/') - i++; - strcpy(tmp, &fname[i]); - - while ((c = (char *) strchr(tmp, '/'))) /* we are still dired searching */ - { - strncpy(working_tmp, tmp, c - tmp); - working_tmp[c - tmp] = '\0'; - for (i = 0; i < strlen(c) - 1; i++) - tmp[i] = c[i + 1]; - tmp[i] = '\0'; - - if (!(pino = jffs2_1pass_find_inode(pL, working_tmp, pino))) { - putstr("find_inode failed for name="); - putstr(working_tmp); - putstr("\r\n"); - return 0; - } - } - /* this is for the bare filename, directories have already been mapped */ - if (!(pino = jffs2_1pass_find_inode(pL, tmp, pino))) { - putstr("find_inode failed for name="); - putstr(tmp); - putstr("\r\n"); - return 0; - } - return pino; - -} - -static u32 -jffs2_1pass_resolve_inode(struct b_lists * pL, u32 ino) -{ - struct b_dirent *jDir; - struct b_inode *jNode; - u8 jDirFoundType = 0; - u32 jDirFoundIno = 0; - u32 jDirFoundPino = 0; - char tmp[JFFS2_MAX_NAME_LEN + 1]; - u32 version = 0; - u32 pino; - - /* we need to search all and return the inode with the highest version */ - for (jDir = (struct b_dirent *)pL->dir.listHead; jDir; jDir = jDir->next) { - if (ino == jDir->ino) { - if (jDir->version < version) - continue; - - if (jDir->version == version && jDirFoundType) { - /* I'm pretty sure this isn't legal */ - putstr(" ** ERROR ** "); -/* putnstr(jDir->name, jDir->nsize); */ -/* putLabeledWord(" has dup version (resolve) = ", */ -/* version); */ - } - - jDirFoundType = jDir->type; - jDirFoundIno = jDir->ino; - jDirFoundPino = jDir->pino; - version = jDir->version; - } - } - /* now we found the right entry again. (shoulda returned inode*) */ - if (jDirFoundType != DT_LNK) - return jDirFoundIno; - - /* it's a soft link so we follow it again. */ - for (jNode = (struct b_inode *)pL->frag.listHead; jNode; jNode = jNode->next) { - if (jNode->ino == jDirFoundIno) { - size_t len = jNode->csize; - nand_read(nand, jNode->offset + sizeof(struct jffs2_raw_inode), &len, &tmp); - tmp[jNode->csize] = '\0'; - break; - } - } - /* ok so the name of the new file to find is in tmp */ - /* if it starts with a slash it is root based else shared dirs */ - if (tmp[0] == '/') - pino = 1; - else - pino = jDirFoundPino; - - return jffs2_1pass_search_inode(pL, tmp, pino); -} - -static u32 -jffs2_1pass_search_list_inodes(struct b_lists * pL, const char *fname, u32 pino) -{ - int i; - char tmp[256]; - char working_tmp[256]; - char *c; - - /* discard any leading slash */ - i = 0; - while (fname[i] == '/') - i++; - strcpy(tmp, &fname[i]); - working_tmp[0] = '\0'; - while ((c = (char *) strchr(tmp, '/'))) /* we are still dired searching */ - { - strncpy(working_tmp, tmp, c - tmp); - working_tmp[c - tmp] = '\0'; - for (i = 0; i < strlen(c) - 1; i++) - tmp[i] = c[i + 1]; - tmp[i] = '\0'; - /* only a failure if we arent looking at top level */ - if (!(pino = jffs2_1pass_find_inode(pL, working_tmp, pino)) && - (working_tmp[0])) { - putstr("find_inode failed for name="); - putstr(working_tmp); - putstr("\r\n"); - return 0; - } - } - - if (tmp[0] && !(pino = jffs2_1pass_find_inode(pL, tmp, pino))) { - putstr("find_inode failed for name="); - putstr(tmp); - putstr("\r\n"); - return 0; - } - /* this is for the bare filename, directories have already been mapped */ - if (!(pino = jffs2_1pass_list_inodes(pL, pino))) { - putstr("find_inode failed for name="); - putstr(tmp); - putstr("\r\n"); - return 0; - } - return pino; - -} - -unsigned char -jffs2_1pass_rescan_needed(struct part_info *part) -{ - struct b_node *b; - struct jffs2_unknown_node onode; - struct jffs2_unknown_node *node; - struct b_lists *pL = (struct b_lists *)part->jffs2_priv; - - if (part->jffs2_priv == 0){ - DEBUGF ("rescan: First time in use\n"); - return 1; - } - /* if we have no list, we need to rescan */ - if (pL->frag.listCount == 0) { - DEBUGF ("rescan: fraglist zero\n"); - return 1; - } - - /* or if we are scanning a new partition */ - if (pL->partOffset != part->offset) { - DEBUGF ("rescan: different partition\n"); - return 1; - } - - /* FIXME */ - return 0; -} - -#ifdef DEBUG_FRAGMENTS -static void -dump_fragments(struct b_lists *pL) -{ - struct b_node *b; - struct jffs2_raw_inode ojNode; - struct jffs2_raw_inode *jNode; - - putstr("\r\n\r\n******The fragment Entries******\r\n"); - b = pL->frag.listHead; - while (b) { - jNode = (struct jffs2_raw_inode *) get_fl_mem(b->offset, - sizeof(ojNode), &ojNode); - putLabeledWord("\r\n\tbuild_list: FLASH_OFFSET = ", b->offset); - putLabeledWord("\tbuild_list: totlen = ", jNode->totlen); - putLabeledWord("\tbuild_list: inode = ", jNode->ino); - putLabeledWord("\tbuild_list: version = ", jNode->version); - putLabeledWord("\tbuild_list: isize = ", jNode->isize); - putLabeledWord("\tbuild_list: atime = ", jNode->atime); - putLabeledWord("\tbuild_list: offset = ", jNode->offset); - putLabeledWord("\tbuild_list: csize = ", jNode->csize); - putLabeledWord("\tbuild_list: dsize = ", jNode->dsize); - putLabeledWord("\tbuild_list: compr = ", jNode->compr); - putLabeledWord("\tbuild_list: usercompr = ", jNode->usercompr); - putLabeledWord("\tbuild_list: flags = ", jNode->flags); - putLabeledWord("\tbuild_list: offset = ", b->offset); /* FIXME: ? [RS] */ - b = b->next; - } -} -#endif - -#ifdef DEBUG_DIRENTS -static void -dump_dirents(struct b_lists *pL) -{ - struct b_node *b; - struct jffs2_raw_dirent *jDir; - - putstr("\r\n\r\n******The directory Entries******\r\n"); - b = pL->dir.listHead; - while (b) { - jDir = (struct jffs2_raw_dirent *) get_node_mem(b->offset); - putstr("\r\n"); - putnstr(jDir->name, jDir->nsize); - putLabeledWord("\r\n\tbuild_list: magic = ", jDir->magic); - putLabeledWord("\tbuild_list: nodetype = ", jDir->nodetype); - putLabeledWord("\tbuild_list: hdr_crc = ", jDir->hdr_crc); - putLabeledWord("\tbuild_list: pino = ", jDir->pino); - putLabeledWord("\tbuild_list: version = ", jDir->version); - putLabeledWord("\tbuild_list: ino = ", jDir->ino); - putLabeledWord("\tbuild_list: mctime = ", jDir->mctime); - putLabeledWord("\tbuild_list: nsize = ", jDir->nsize); - putLabeledWord("\tbuild_list: type = ", jDir->type); - putLabeledWord("\tbuild_list: node_crc = ", jDir->node_crc); - putLabeledWord("\tbuild_list: name_crc = ", jDir->name_crc); - putLabeledWord("\tbuild_list: offset = ", b->offset); /* FIXME: ? [RS] */ - b = b->next; - put_fl_mem(jDir); - } -} -#endif - -static int -jffs2_fill_scan_buf(nand_info_t *nand, unsigned char *buf, - unsigned ofs, unsigned len) -{ - int ret; - unsigned olen; - - olen = len; - ret = nand_read(nand, ofs, &olen, buf); - if (ret) { - printf("nand_read(0x%x bytes from 0x%x) returned %d\n", len, ofs, ret); - return ret; - } - if (olen < len) { - printf("Read at 0x%x gave only 0x%x bytes\n", ofs, olen); - return -1; - } - return 0; -} - -#define EMPTY_SCAN_SIZE 1024 -static u32 -jffs2_1pass_build_lists(struct part_info * part) -{ - struct b_lists *pL; - struct jffs2_unknown_node *node; - unsigned nr_blocks, sectorsize, ofs, offset; - char *buf; - int i; - u32 counter = 0; - u32 counter4 = 0; - u32 counterF = 0; - u32 counterN = 0; - - struct mtdids *id = part->dev->id; - nand = nand_info + id->num; - - /* if we are building a list we need to refresh the cache. */ - jffs_init_1pass_list(part); - pL = (struct b_lists *)part->jffs2_priv; - pL->partOffset = part->offset; - puts ("Scanning JFFS2 FS: "); - - sectorsize = nand->erasesize; - nr_blocks = part->size / sectorsize; - buf = malloc(sectorsize); - if (!buf) - return 0; - - for (i = 0; i < nr_blocks; i++) { - printf("\b\b%c ", spinner[counter++ % sizeof(spinner)]); - - offset = part->offset + i * sectorsize; - - if (nand_block_isbad(nand, offset)) - continue; - - if (jffs2_fill_scan_buf(nand, buf, offset, EMPTY_SCAN_SIZE)) - return 0; - - ofs = 0; - /* Scan only 4KiB of 0xFF before declaring it's empty */ - while (ofs < EMPTY_SCAN_SIZE && *(uint32_t *)(&buf[ofs]) == 0xFFFFFFFF) - ofs += 4; - if (ofs == EMPTY_SCAN_SIZE) - continue; - - if (jffs2_fill_scan_buf(nand, buf + EMPTY_SCAN_SIZE, offset + EMPTY_SCAN_SIZE, sectorsize - EMPTY_SCAN_SIZE)) - return 0; - offset += ofs; - - while (ofs < sectorsize - sizeof(struct jffs2_unknown_node)) { - node = (struct jffs2_unknown_node *)&buf[ofs]; - if (node->magic != JFFS2_MAGIC_BITMASK || !hdr_crc(node)) { - offset += 4; - ofs += 4; - counter4++; - continue; - } - /* if its a fragment add it */ - if (node->nodetype == JFFS2_NODETYPE_INODE && - inode_crc((struct jffs2_raw_inode *) node)) { - if (insert_inode(&pL->frag, (struct jffs2_raw_inode *) node, - offset) == NULL) { - return 0; - } - } else if (node->nodetype == JFFS2_NODETYPE_DIRENT && - dirent_crc((struct jffs2_raw_dirent *) node) && - dirent_name_crc((struct jffs2_raw_dirent *) node)) { - if (! (counterN%100)) - puts ("\b\b. "); - if (insert_dirent(&pL->dir, (struct jffs2_raw_dirent *) node, - offset) == NULL) { - return 0; - } - counterN++; - } else if (node->nodetype == JFFS2_NODETYPE_CLEANMARKER) { - if (node->totlen != sizeof(struct jffs2_unknown_node)) - printf("OOPS Cleanmarker has bad size " - "%d != %d\n", node->totlen, - sizeof(struct jffs2_unknown_node)); - } else if (node->nodetype == JFFS2_NODETYPE_PADDING) { - if (node->totlen < sizeof(struct jffs2_unknown_node)) - printf("OOPS Padding has bad size " - "%d < %d\n", node->totlen, - sizeof(struct jffs2_unknown_node)); - } else { - printf("Unknown node type: %x len %d " - "offset 0x%x\n", node->nodetype, - node->totlen, offset); - } - offset += ((node->totlen + 3) & ~3); - ofs += ((node->totlen + 3) & ~3); - counterF++; - } - } - - putstr("\b\b done.\r\n"); /* close off the dots */ - - -#ifdef DEBUG_DIRENTS - dump_dirents(pL); -#endif - -#ifdef DEBUG_FRAGMENTS - dump_fragments(pL); -#endif - - /* give visual feedback that we are done scanning the flash */ - led_blink(0x0, 0x0, 0x1, 0x1); /* off, forever, on 100ms, off 100ms */ - free(buf); - - return 1; -} - - -static u32 -jffs2_1pass_fill_info(struct b_lists * pL, struct b_jffs2_info * piL) -{ - struct b_node *b; - struct jffs2_raw_inode ojNode; - struct jffs2_raw_inode *jNode; - int i; - - for (i = 0; i < JFFS2_NUM_COMPR; i++) { - piL->compr_info[i].num_frags = 0; - piL->compr_info[i].compr_sum = 0; - piL->compr_info[i].decompr_sum = 0; - } -/* FIXME - b = pL->frag.listHead; - while (b) { - jNode = (struct jffs2_raw_inode *) get_fl_mem(b->offset, - sizeof(ojNode), &ojNode); - if (jNode->compr < JFFS2_NUM_COMPR) { - piL->compr_info[jNode->compr].num_frags++; - piL->compr_info[jNode->compr].compr_sum += jNode->csize; - piL->compr_info[jNode->compr].decompr_sum += jNode->dsize; - } - b = b->next; - } -*/ - return 0; -} - - -static struct b_lists * -jffs2_get_list(struct part_info * part, const char *who) -{ - if (jffs2_1pass_rescan_needed(part)) { - if (!jffs2_1pass_build_lists(part)) { - printf("%s: Failed to scan JFFSv2 file structure\n", who); - return NULL; - } - } - return (struct b_lists *)part->jffs2_priv; -} - - -/* Print directory / file contents */ -u32 -jffs2_1pass_ls(struct part_info * part, const char *fname) -{ - struct b_lists *pl; - long ret = 0; - u32 inode; - - if (! (pl = jffs2_get_list(part, "ls"))) - return 0; - - if (! (inode = jffs2_1pass_search_list_inodes(pl, fname, 1))) { - putstr("ls: Failed to scan jffs2 file structure\r\n"); - return 0; - } - - - return ret; -} - - -/* Load a file from flash into memory. fname can be a full path */ -u32 -jffs2_1pass_load(char *dest, struct part_info * part, const char *fname) -{ - - struct b_lists *pl; - long ret = 0; - u32 inode; - - if (! (pl = jffs2_get_list(part, "load"))) - return 0; - - if (! (inode = jffs2_1pass_search_inode(pl, fname, 1))) { - putstr("load: Failed to find inode\r\n"); - return 0; - } - - /* Resolve symlinks */ - if (! (inode = jffs2_1pass_resolve_inode(pl, inode))) { - putstr("load: Failed to resolve inode structure\r\n"); - return 0; - } - - if ((ret = jffs2_1pass_read_inode(pl, inode, dest, NULL)) < 0) { - putstr("load: Failed to read inode\r\n"); - return 0; - } - - DEBUGF ("load: loaded '%s' to 0x%lx (%ld bytes)\n", fname, - (unsigned long) dest, ret); - return ret; -} - -/* Return information about the fs on this partition */ -u32 -jffs2_1pass_info(struct part_info * part) -{ - struct b_jffs2_info info; - struct b_lists *pl; - int i; - - if (! (pl = jffs2_get_list(part, "info"))) - return 0; - - jffs2_1pass_fill_info(pl, &info); - for (i = 0; i < JFFS2_NUM_COMPR; i++) { - printf ("Compression: %s\n" - "\tfrag count: %d\n" - "\tcompressed sum: %d\n" - "\tuncompressed sum: %d\n", - compr_names[i], - info.compr_info[i].num_frags, - info.compr_info[i].compr_sum, - info.compr_info[i].decompr_sum); - } - return 1; -} - -#endif /* CFG_CMD_JFFS2 */ diff --git a/fs/jffs2/jffs2_nand_private.h b/fs/jffs2/jffs2_nand_private.h deleted file mode 100644 index b2cfa16ec0..0000000000 --- a/fs/jffs2/jffs2_nand_private.h +++ /dev/null @@ -1,126 +0,0 @@ -#ifndef jffs2_private_h -#define jffs2_private_h - -#include <jffs2/jffs2.h> - -struct b_node { - struct b_node *next; -}; - -struct b_inode { - struct b_inode *next; - u32 offset; /* physical offset to beginning of real inode */ - u32 version; - u32 ino; - u32 isize; - u32 csize; -}; - -struct b_dirent { - struct b_dirent *next; - u32 offset; /* physical offset to beginning of real dirent */ - u32 version; - u32 pino; - u32 ino; - unsigned int nhash; - unsigned char nsize; - unsigned char type; -}; - -struct b_list { - struct b_node *listTail; - struct b_node *listHead; - unsigned int listCount; - struct mem_block *listMemBase; -}; - -struct b_lists { - char *partOffset; - struct b_list dir; - struct b_list frag; -}; - -struct b_compr_info { - u32 num_frags; - u32 compr_sum; - u32 decompr_sum; -}; - -struct b_jffs2_info { - struct b_compr_info compr_info[JFFS2_NUM_COMPR]; -}; - -static inline int -hdr_crc(struct jffs2_unknown_node *node) -{ - u32 crc = crc32_no_comp(0, (unsigned char *)node, sizeof(struct jffs2_unknown_node) - 4); - if (node->hdr_crc != crc) { - return 0; - } else { - return 1; - } -} - -static inline int -dirent_crc(struct jffs2_raw_dirent *node) -{ - if (node->node_crc != crc32_no_comp(0, (unsigned char *)node, sizeof(struct jffs2_raw_dirent) - 8)) { - return 0; - } else { - return 1; - } -} - -static inline int -dirent_name_crc(struct jffs2_raw_dirent *node) -{ - if (node->name_crc != crc32_no_comp(0, (unsigned char *)&(node->name), node->nsize)) { - return 0; - } else { - return 1; - } -} - -static inline int -inode_crc(struct jffs2_raw_inode *node) -{ - if (node->node_crc != crc32_no_comp(0, (unsigned char *)node, sizeof(struct jffs2_raw_inode) - 8)) { - return 0; - } else { - return 1; - } -} - -/* Borrowed from include/linux/dcache.h */ - -/* Name hashing routines. Initial hash value */ -/* Hash courtesy of the R5 hash in reiserfs modulo sign bits */ -#define init_name_hash() 0 - -/* partial hash update function. Assume roughly 4 bits per character */ -static inline unsigned long -partial_name_hash(unsigned long c, unsigned long prevhash) -{ - return (prevhash + (c << 4) + (c >> 4)) * 11; -} - -/* - * Finally: cut down the number of bits to a int value (and try to avoid - * losing bits) - */ -static inline unsigned long end_name_hash(unsigned long hash) -{ - return (unsigned int) hash; -} - -/* Compute the hash for a name string. */ -static inline unsigned int -full_name_hash(const unsigned char *name, unsigned int len) -{ - unsigned long hash = init_name_hash(); - while (len--) - hash = partial_name_hash(*name++, hash); - return end_name_hash(hash); -} - -#endif /* jffs2_private.h */ diff --git a/fs/jffs2/jffs2_private.h b/fs/jffs2/jffs2_private.h deleted file mode 100644 index 4527544727..0000000000 --- a/fs/jffs2/jffs2_private.h +++ /dev/null @@ -1,93 +0,0 @@ -#ifndef jffs2_private_h -#define jffs2_private_h - -#include <jffs2/jffs2.h> - - -struct b_node { - u32 offset; - struct b_node *next; -}; - -struct b_list { - struct b_node *listTail; - struct b_node *listHead; -#ifdef CFG_JFFS2_SORT_FRAGMENTS - struct b_node *listLast; - int (*listCompare)(struct b_node *new, struct b_node *node); - u32 listLoops; -#endif - u32 listCount; - struct mem_block *listMemBase; -}; - -struct b_lists { - struct b_list dir; - struct b_list frag; - -}; - -struct b_compr_info { - u32 num_frags; - u32 compr_sum; - u32 decompr_sum; -}; - -struct b_jffs2_info { - struct b_compr_info compr_info[JFFS2_NUM_COMPR]; -}; - -static inline int -hdr_crc(struct jffs2_unknown_node *node) -{ - u32 crc = crc32_no_comp(0, (unsigned char *)node, sizeof(struct jffs2_unknown_node) - 4); - if (node->hdr_crc != crc) { - return 0; - } else { - return 1; - } -} - -static inline int -dirent_crc(struct jffs2_raw_dirent *node) -{ - if (node->node_crc != crc32_no_comp(0, (unsigned char *)node, sizeof(struct jffs2_raw_dirent) - 8)) { - return 0; - } else { - return 1; - } -} - -static inline int -dirent_name_crc(struct jffs2_raw_dirent *node) -{ - if (node->name_crc != crc32_no_comp(0, (unsigned char *)&(node->name), node->nsize)) { - return 0; - } else { - return 1; - } -} - -static inline int -inode_crc(struct jffs2_raw_inode *node) -{ - if (node->node_crc != crc32_no_comp(0, (unsigned char *)node, sizeof(struct jffs2_raw_inode) - 8)) { - return 0; - } else { - return 1; - } -} - -static inline int -data_crc(struct jffs2_raw_inode *node) -{ - if (node->data_crc != crc32_no_comp(0, (unsigned char *) - ((int) &node->node_crc + sizeof (node->node_crc)), - node->csize)) { - return 0; - } else { - return 1; - } -} - -#endif /* jffs2_private.h */ diff --git a/fs/jffs2/mini_inflate.c b/fs/jffs2/mini_inflate.c deleted file mode 100644 index 7940f09317..0000000000 --- a/fs/jffs2/mini_inflate.c +++ /dev/null @@ -1,389 +0,0 @@ -/*------------------------------------------------------------------------- - * Filename: mini_inflate.c - * Version: $Id: mini_inflate.c,v 1.3 2002/01/24 22:58:42 rfeany Exp $ - * Copyright: Copyright (C) 2001, Russ Dill - * Author: Russ Dill <Russ.Dill@asu.edu> - * Description: Mini inflate implementation (RFC 1951) - *-----------------------------------------------------------------------*/ -/* - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include <config.h> - -#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) - -#include <jffs2/mini_inflate.h> - -/* The order that the code lengths in section 3.2.7 are in */ -static unsigned char huffman_order[] = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, - 11, 4, 12, 3, 13, 2, 14, 1, 15}; - -inline void cramfs_memset(int *s, const int c, size n) -{ - n--; - for (;n > 0; n--) s[n] = c; - s[0] = c; -} - -/* associate a stream with a block of data and reset the stream */ -static void init_stream(struct bitstream *stream, unsigned char *data, - void *(*inflate_memcpy)(void *, const void *, size)) -{ - stream->error = NO_ERROR; - stream->memcpy = inflate_memcpy; - stream->decoded = 0; - stream->data = data; - stream->bit = 0; /* The first bit of the stream is the lsb of the - * first byte */ - - /* really sorry about all this initialization, think of a better way, - * let me know and it will get cleaned up */ - stream->codes.bits = 8; - stream->codes.num_symbols = 19; - stream->codes.lengths = stream->code_lengths; - stream->codes.symbols = stream->code_symbols; - stream->codes.count = stream->code_count; - stream->codes.first = stream->code_first; - stream->codes.pos = stream->code_pos; - - stream->lengths.bits = 16; - stream->lengths.num_symbols = 288; - stream->lengths.lengths = stream->length_lengths; - stream->lengths.symbols = stream->length_symbols; - stream->lengths.count = stream->length_count; - stream->lengths.first = stream->length_first; - stream->lengths.pos = stream->length_pos; - - stream->distance.bits = 16; - stream->distance.num_symbols = 32; - stream->distance.lengths = stream->distance_lengths; - stream->distance.symbols = stream->distance_symbols; - stream->distance.count = stream->distance_count; - stream->distance.first = stream->distance_first; - stream->distance.pos = stream->distance_pos; - -} - -/* pull 'bits' bits out of the stream. The last bit pulled it returned as the - * msb. (section 3.1.1) - */ -inline unsigned long pull_bits(struct bitstream *stream, - const unsigned int bits) -{ - unsigned long ret; - int i; - - ret = 0; - for (i = 0; i < bits; i++) { - ret += ((*(stream->data) >> stream->bit) & 1) << i; - - /* if, before incrementing, we are on bit 7, - * go to the lsb of the next byte */ - if (stream->bit++ == 7) { - stream->bit = 0; - stream->data++; - } - } - return ret; -} - -inline int pull_bit(struct bitstream *stream) -{ - int ret = ((*(stream->data) >> stream->bit) & 1); - if (stream->bit++ == 7) { - stream->bit = 0; - stream->data++; - } - return ret; -} - -/* discard bits up to the next whole byte */ -static void discard_bits(struct bitstream *stream) -{ - if (stream->bit != 0) { - stream->bit = 0; - stream->data++; - } -} - -/* No decompression, the data is all literals (section 3.2.4) */ -static void decompress_none(struct bitstream *stream, unsigned char *dest) -{ - unsigned int length; - - discard_bits(stream); - length = *(stream->data++); - length += *(stream->data++) << 8; - pull_bits(stream, 16); /* throw away the inverse of the size */ - - stream->decoded += length; - stream->memcpy(dest, stream->data, length); - stream->data += length; -} - -/* Read in a symbol from the stream (section 3.2.2) */ -static int read_symbol(struct bitstream *stream, struct huffman_set *set) -{ - int bits = 0; - int code = 0; - while (!(set->count[bits] && code < set->first[bits] + - set->count[bits])) { - code = (code << 1) + pull_bit(stream); - if (++bits > set->bits) { - /* error decoding (corrupted data?) */ - stream->error = CODE_NOT_FOUND; - return -1; - } - } - return set->symbols[set->pos[bits] + code - set->first[bits]]; -} - -/* decompress a stream of data encoded with the passed length and distance - * huffman codes */ -static void decompress_huffman(struct bitstream *stream, unsigned char *dest) -{ - struct huffman_set *lengths = &(stream->lengths); - struct huffman_set *distance = &(stream->distance); - - int symbol, length, dist, i; - - do { - if ((symbol = read_symbol(stream, lengths)) < 0) return; - if (symbol < 256) { - *(dest++) = symbol; /* symbol is a literal */ - stream->decoded++; - } else if (symbol > 256) { - /* Determine the length of the repitition - * (section 3.2.5) */ - if (symbol < 265) length = symbol - 254; - else if (symbol == 285) length = 258; - else { - length = pull_bits(stream, (symbol - 261) >> 2); - length += (4 << ((symbol - 261) >> 2)) + 3; - length += ((symbol - 1) % 4) << - ((symbol - 261) >> 2); - } - - /* Determine how far back to go */ - if ((symbol = read_symbol(stream, distance)) < 0) - return; - if (symbol < 4) dist = symbol + 1; - else { - dist = pull_bits(stream, (symbol - 2) >> 1); - dist += (2 << ((symbol - 2) >> 1)) + 1; - dist += (symbol % 2) << ((symbol - 2) >> 1); - } - stream->decoded += length; - for (i = 0; i < length; i++) { - *dest = dest[-dist]; - dest++; - } - } - } while (symbol != 256); /* 256 is the end of the data block */ -} - -/* Fill the lookup tables (section 3.2.2) */ -static void fill_code_tables(struct huffman_set *set) -{ - int code = 0, i, length; - - /* fill in the first code of each bit length, and the pos pointer */ - set->pos[0] = 0; - for (i = 1; i < set->bits; i++) { - code = (code + set->count[i - 1]) << 1; - set->first[i] = code; - set->pos[i] = set->pos[i - 1] + set->count[i - 1]; - } - - /* Fill in the table of symbols in order of their huffman code */ - for (i = 0; i < set->num_symbols; i++) { - if ((length = set->lengths[i])) - set->symbols[set->pos[length]++] = i; - } - - /* reset the pos pointer */ - for (i = 1; i < set->bits; i++) set->pos[i] -= set->count[i]; -} - -static void init_code_tables(struct huffman_set *set) -{ - cramfs_memset(set->lengths, 0, set->num_symbols); - cramfs_memset(set->count, 0, set->bits); - cramfs_memset(set->first, 0, set->bits); -} - -/* read in the huffman codes for dynamic decoding (section 3.2.7) */ -static void decompress_dynamic(struct bitstream *stream, unsigned char *dest) -{ - /* I tried my best to minimize the memory footprint here, while still - * keeping up performance. I really dislike the _lengths[] tables, but - * I see no way of eliminating them without a sizable performance - * impact. The first struct table keeps track of stats on each bit - * length. The _length table keeps a record of the bit length of each - * symbol. The _symbols table is for looking up symbols by the huffman - * code (the pos element points to the first place in the symbol table - * where that bit length occurs). I also hate the initization of these - * structs, if someone knows how to compact these, lemme know. */ - - struct huffman_set *codes = &(stream->codes); - struct huffman_set *lengths = &(stream->lengths); - struct huffman_set *distance = &(stream->distance); - - int hlit = pull_bits(stream, 5) + 257; - int hdist = pull_bits(stream, 5) + 1; - int hclen = pull_bits(stream, 4) + 4; - int length, curr_code, symbol, i, last_code; - - last_code = 0; - - init_code_tables(codes); - init_code_tables(lengths); - init_code_tables(distance); - - /* fill in the count of each bit length' as well as the lengths - * table */ - for (i = 0; i < hclen; i++) { - length = pull_bits(stream, 3); - codes->lengths[huffman_order[i]] = length; - if (length) codes->count[length]++; - - } - fill_code_tables(codes); - - /* Do the same for the length codes, being carefull of wrap through - * to the distance table */ - curr_code = 0; - while (curr_code < hlit) { - if ((symbol = read_symbol(stream, codes)) < 0) return; - if (symbol == 0) { - curr_code++; - last_code = 0; - } else if (symbol < 16) { /* Literal length */ - lengths->lengths[curr_code] = last_code = symbol; - lengths->count[symbol]++; - curr_code++; - } else if (symbol == 16) { /* repeat the last symbol 3 - 6 - * times */ - length = 3 + pull_bits(stream, 2); - for (;length; length--, curr_code++) - if (curr_code < hlit) { - lengths->lengths[curr_code] = - last_code; - lengths->count[last_code]++; - } else { /* wrap to the distance table */ - distance->lengths[curr_code - hlit] = - last_code; - distance->count[last_code]++; - } - } else if (symbol == 17) { /* repeat a bit length 0 */ - curr_code += 3 + pull_bits(stream, 3); - last_code = 0; - } else { /* same, but more times */ - curr_code += 11 + pull_bits(stream, 7); - last_code = 0; - } - } - fill_code_tables(lengths); - - /* Fill the distance table, don't need to worry about wrapthrough - * here */ - curr_code -= hlit; - while (curr_code < hdist) { - if ((symbol = read_symbol(stream, codes)) < 0) return; - if (symbol == 0) { - curr_code++; - last_code = 0; - } else if (symbol < 16) { - distance->lengths[curr_code] = last_code = symbol; - distance->count[symbol]++; - curr_code++; - } else if (symbol == 16) { - length = 3 + pull_bits(stream, 2); - for (;length; length--, curr_code++) { - distance->lengths[curr_code] = - last_code; - distance->count[last_code]++; - } - } else if (symbol == 17) { - curr_code += 3 + pull_bits(stream, 3); - last_code = 0; - } else { - curr_code += 11 + pull_bits(stream, 7); - last_code = 0; - } - } - fill_code_tables(distance); - - decompress_huffman(stream, dest); -} - -/* fill in the length and distance huffman codes for fixed encoding - * (section 3.2.6) */ -static void decompress_fixed(struct bitstream *stream, unsigned char *dest) -{ - /* let gcc fill in the initial values */ - struct huffman_set *lengths = &(stream->lengths); - struct huffman_set *distance = &(stream->distance); - - cramfs_memset(lengths->count, 0, 16); - cramfs_memset(lengths->first, 0, 16); - cramfs_memset(lengths->lengths, 8, 144); - cramfs_memset(lengths->lengths + 144, 9, 112); - cramfs_memset(lengths->lengths + 256, 7, 24); - cramfs_memset(lengths->lengths + 280, 8, 8); - lengths->count[7] = 24; - lengths->count[8] = 152; - lengths->count[9] = 112; - - cramfs_memset(distance->count, 0, 16); - cramfs_memset(distance->first, 0, 16); - cramfs_memset(distance->lengths, 5, 32); - distance->count[5] = 32; - - - fill_code_tables(lengths); - fill_code_tables(distance); - - - decompress_huffman(stream, dest); -} - -/* returns the number of bytes decoded, < 0 if there was an error. Note that - * this function assumes that the block starts on a byte boundry - * (non-compliant, but I don't see where this would happen). section 3.2.3 */ -long decompress_block(unsigned char *dest, unsigned char *source, - void *(*inflate_memcpy)(void *, const void *, size)) -{ - int bfinal, btype; - struct bitstream stream; - - init_stream(&stream, source, inflate_memcpy); - do { - bfinal = pull_bit(&stream); - btype = pull_bits(&stream, 2); - if (btype == NO_COMP) decompress_none(&stream, dest + stream.decoded); - else if (btype == DYNAMIC_COMP) - decompress_dynamic(&stream, dest + stream.decoded); - else if (btype == FIXED_COMP) decompress_fixed(&stream, dest + stream.decoded); - else stream.error = COMP_UNKNOWN; - } while (!bfinal && !stream.error); - - return stream.error ? -stream.error : stream.decoded; -} - -#endif /* CFG_CMD_JFFS2 */ diff --git a/fs/reiserfs/Makefile b/fs/reiserfs/Makefile deleted file mode 100644 index e8711a411a..0000000000 --- a/fs/reiserfs/Makefile +++ /dev/null @@ -1,52 +0,0 @@ -# -# (C) Copyright 2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# (C) Copyright 2003 -# Pavel Bartusek, Sysgo Real-Time Solutions AG, pba@sysgo.de -# -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)libreiserfs.a - -AOBJS = -COBJS = reiserfs.o dev.o mode_string.o - -SRCS := $(AOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(AOBJS) $(COBJS)) - -#CPPFLAGS += - -all: $(LIB) $(AOBJS) - -$(LIB): $(obj).depend $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/fs/reiserfs/dev.c b/fs/reiserfs/dev.c deleted file mode 100644 index 6f6056f337..0000000000 --- a/fs/reiserfs/dev.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * (C) Copyright 2003 - 2004 - * Sysgo AG, <www.elinos.com>, Pavel Bartusek <pba@sysgo.com> - * - * 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 <common.h> -#if (CONFIG_COMMANDS & CFG_CMD_REISER) - -#include <config.h> -#include <reiserfs.h> - -#include "reiserfs_private.h" - -static block_dev_desc_t *reiserfs_block_dev_desc; -static disk_partition_t part_info; - - -int reiserfs_set_blk_dev(block_dev_desc_t *rbdd, int part) -{ - reiserfs_block_dev_desc = rbdd; - - if (part == 0) { - /* disk doesn't use partition table */ - part_info.start = 0; - part_info.size = rbdd->lba; - part_info.blksz = rbdd->blksz; - } else { - if (get_partition_info (reiserfs_block_dev_desc, part, &part_info)) { - return 0; - } - } - return (part_info.size); -} - - -int reiserfs_devread (int sector, int byte_offset, int byte_len, char *buf) -{ - char sec_buf[SECTOR_SIZE]; - unsigned block_len; -/* - unsigned len = byte_len; - u8 *start = buf; -*/ - /* - * Check partition boundaries - */ - if (sector < 0 - || ((sector + ((byte_offset + byte_len - 1) >> SECTOR_BITS)) - >= part_info.size)) { -/* errnum = ERR_OUTSIDE_PART; */ - printf (" ** reiserfs_devread() read outside partition\n"); - return 0; - } - - /* - * Get the read to the beginning of a partition. - */ - sector += byte_offset >> SECTOR_BITS; - byte_offset &= SECTOR_SIZE - 1; - -#if defined(DEBUG) - printf (" <%d, %d, %d> ", sector, byte_offset, byte_len); -#endif - - - if (reiserfs_block_dev_desc == NULL) - return 0; - - - if (byte_offset != 0) { - /* read first part which isn't aligned with start of sector */ - if (reiserfs_block_dev_desc->block_read(reiserfs_block_dev_desc->dev, - part_info.start+sector, 1, (unsigned long *)sec_buf) != 1) { - printf (" ** reiserfs_devread() read error\n"); - return 0; - } - memcpy(buf, sec_buf+byte_offset, min(SECTOR_SIZE-byte_offset, byte_len)); - buf+=min(SECTOR_SIZE-byte_offset, byte_len); - byte_len-=min(SECTOR_SIZE-byte_offset, byte_len); - sector++; - } - - /* read sector aligned part */ - block_len = byte_len & ~(SECTOR_SIZE-1); - if (reiserfs_block_dev_desc->block_read(reiserfs_block_dev_desc->dev, - part_info.start+sector, block_len/SECTOR_SIZE, (unsigned long *)buf) != - block_len/SECTOR_SIZE) { - printf (" ** reiserfs_devread() read error - block\n"); - return 0; - } - buf+=block_len; - byte_len-=block_len; - sector+= block_len/SECTOR_SIZE; - - if ( byte_len != 0 ) { - /* read rest of data which are not in whole sector */ - if (reiserfs_block_dev_desc->block_read(reiserfs_block_dev_desc->dev, - part_info.start+sector, 1, (unsigned long *)sec_buf) != 1) { - printf (" ** reiserfs_devread() read error - last part\n"); - return 0; - } - memcpy(buf, sec_buf, byte_len); - } - - return 1; -} - -#endif /* CFG_CMD_REISERFS */ diff --git a/fs/reiserfs/mode_string.c b/fs/reiserfs/mode_string.c deleted file mode 100644 index bc565fbddd..0000000000 --- a/fs/reiserfs/mode_string.c +++ /dev/null @@ -1,142 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * mode_string implementation for busybox - * - * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> - * - * 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 - * - */ - -/* Aug 13, 2003 - * Fix a bug reported by junkio@cox.net involving the mode_chars index. - */ - - -#include <common.h> -#if (CONFIG_COMMANDS & CFG_CMD_REISER) -#include <linux/stat.h> - -#if ( S_ISUID != 04000 ) || ( S_ISGID != 02000 ) || ( S_ISVTX != 01000 ) \ - || ( S_IRUSR != 00400 ) || ( S_IWUSR != 00200 ) || ( S_IXUSR != 00100 ) \ - || ( S_IRGRP != 00040 ) || ( S_IWGRP != 00020 ) || ( S_IXGRP != 00010 ) \ - || ( S_IROTH != 00004 ) || ( S_IWOTH != 00002 ) || ( S_IXOTH != 00001 ) -#error permission bitflag value assumption(s) violated! -#endif - -#if ( S_IFSOCK!= 0140000 ) || ( S_IFLNK != 0120000 ) \ - || ( S_IFREG != 0100000 ) || ( S_IFBLK != 0060000 ) \ - || ( S_IFDIR != 0040000 ) || ( S_IFCHR != 0020000 ) \ - || ( S_IFIFO != 0010000 ) -#warning mode type bitflag value assumption(s) violated! falling back to larger version - -#if (S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID | S_ISVTX) == 07777 -#undef mode_t -#define mode_t unsigned short -#endif - -static const mode_t mode_flags[] = { - S_IRUSR, S_IWUSR, S_IXUSR, S_ISUID, - S_IRGRP, S_IWGRP, S_IXGRP, S_ISGID, - S_IROTH, S_IWOTH, S_IXOTH, S_ISVTX -}; - -/* The static const char arrays below are duplicated for the two cases - * because moving them ahead of the mode_flags declaration cause a text - * size increase with the gcc version I'm using. */ - -/* The previous version used "0pcCd?bB-?l?s???". However, the '0', 'C', - * and 'B' types don't appear to be available on linux. So I removed them. */ -static const char type_chars[16] = "?pc?d?b?-?l?s???"; -/* 0123456789abcdef */ -static const char mode_chars[7] = "rwxSTst"; - -const char *bb_mode_string(int mode) -{ - static char buf[12]; - char *p = buf; - - int i, j, k; - - *p = type_chars[ (mode >> 12) & 0xf ]; - i = 0; - do { - j = k = 0; - do { - *++p = '-'; - if (mode & mode_flags[i+j]) { - *p = mode_chars[j]; - k = j; - } - } while (++j < 3); - if (mode & mode_flags[i+j]) { - *p = mode_chars[3 + (k & 2) + ((i&8) >> 3)]; - } - i += 4; - } while (i < 12); - - /* Note: We don't bother with nul termination because bss initialization - * should have taken care of that for us. If the user scribbled in buf - * memory, they deserve whatever happens. But we'll at least assert. */ - if (buf[10] != 0) return NULL; - - return buf; -} - -#else - -/* The previous version used "0pcCd?bB-?l?s???". However, the '0', 'C', - * and 'B' types don't appear to be available on linux. So I removed them. */ -static const char type_chars[16] = "?pc?d?b?-?l?s???"; -/* 0123456789abcdef */ -static const char mode_chars[7] = "rwxSTst"; - -const char *bb_mode_string(int mode) -{ - static char buf[12]; - char *p = buf; - - int i, j, k, m; - - *p = type_chars[ (mode >> 12) & 0xf ]; - i = 0; - m = 0400; - do { - j = k = 0; - do { - *++p = '-'; - if (mode & m) { - *p = mode_chars[j]; - k = j; - } - m >>= 1; - } while (++j < 3); - ++i; - if (mode & (010000 >> i)) { - *p = mode_chars[3 + (k & 2) + (i == 3)]; - } - } while (i < 3); - - /* Note: We don't bother with nul termination because bss initialization - * should have taken care of that for us. If the user scribbled in buf - * memory, they deserve whatever happens. But we'll at least assert. */ - if (buf[10] != 0) return NULL; - - return buf; -} - -#endif - -#endif /* CFG_CMD_REISER */ diff --git a/fs/reiserfs/reiserfs.c b/fs/reiserfs/reiserfs.c deleted file mode 100644 index c6b8efcf7c..0000000000 --- a/fs/reiserfs/reiserfs.c +++ /dev/null @@ -1,978 +0,0 @@ -/* - * Copyright 2000-2002 by Hans Reiser, licensing governed by reiserfs/README - * - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2000, 2001 Free Software Foundation, Inc. - * - * (C) Copyright 2003 - 2004 - * Sysgo AG, <www.elinos.com>, Pavel Bartusek <pba@sysgo.com> - * - * - * 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. - */ - -/* An implementation for the ReiserFS filesystem ported from GRUB. - * Some parts of this code (mainly the structures and defines) are - * from the original reiser fs code, as found in the linux kernel. - */ - -#include <common.h> -#if (CONFIG_COMMANDS & CFG_CMD_REISER) - -#include <malloc.h> -#include <linux/ctype.h> -#include <linux/time.h> -#include <asm/byteorder.h> -#include <reiserfs.h> - -#include "reiserfs_private.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. - */ - -static char fsys_buf[FSYS_BUFLEN]; -static reiserfs_error_t errnum = ERR_NONE; -static int print_possibilities; -static unsigned int filepos, filemax; - -static 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; -} - -static void sd_print_item (struct item_head * ih, char * item) -{ - char filetime[30]; - time_t ttime; - - if (stat_data_v1 (ih)) { - struct stat_data_v1 * sd = (struct stat_data_v1 *)item; - ttime = sd_v1_mtime(sd); - ctime_r(&ttime, filetime); - printf ("%-10s %4hd %6d %6d %9d %24.24s", - bb_mode_string(sd_v1_mode(sd)), sd_v1_nlink(sd),sd_v1_uid(sd), sd_v1_gid(sd), - sd_v1_size(sd), filetime); - } else { - struct stat_data * sd = (struct stat_data *)item; - ttime = sd_v2_mtime(sd); - ctime_r(&ttime, filetime); - printf ("%-10s %4d %6d %6d %9d %24.24s", - bb_mode_string(sd_v2_mode(sd)), sd_v2_nlink(sd),sd_v2_uid(sd),sd_v2_gid(sd), - (__u32) sd_v2_size(sd), filetime); - } -} - -static int -journal_read (int block, int len, char *buffer) -{ - return reiserfs_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 (unsigned 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 (__le32_to_cpu(*journal_table) != 0xffffffff) - { - /* Search for the blockNr in cached journal */ - j_len = __le32_to_cpu(*journal_table++); - while (i++ < j_len) - { - if (__le32_to_cpu(*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 = __le32_to_cpu(desc.j_len); - while (i < j_len && i < JOURNAL_TRANS_HALF) - if (__le32_to_cpu(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 (__le32_to_cpu(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 reiserfs_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 = __le32_to_cpu(header.j_first_unflushed_offset); - if (desc_block >= block_count) - return 0; - - INFO->journal_first_desc = desc_block; - next_trans_id = __le32_to_cpu(header.j_last_flush_trans_id) + 1; - -#ifdef REISERDEBUG - printf ("journal_init: last flushed %d\n", - __le32_to_cpu(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 - || __le32_to_cpu(desc.j_trans_id) != next_trans_id - || __le32_to_cpu(desc.j_mount_id) != __le32_to_cpu(header.j_mount_id)) - /* no more valid transactions */ - break; - - commit_block = (desc_block + __le32_to_cpu(desc.j_len) + 1) & (block_count - 1); - journal_read (commit_block, sizeof (commit), (char *) &commit); - if (__le32_to_cpu(desc.j_trans_id) != commit.j_trans_id - || __le32_to_cpu(desc.j_len) != __le32_to_cpu(commit.j_len)) - /* no more valid transactions */ - break; - -#ifdef REISERDEBUG - printf ("Found valid transaction %d/%d at %d.\n", - __le32_to_cpu(desc.j_trans_id), __le32_to_cpu(desc.j_mount_id), desc_block); -#endif - - next_trans_id++; - if (journal_table < JOURNAL_END) - { - if ((journal_table + 1 + __le32_to_cpu(desc.j_len)) >= JOURNAL_END) - { - /* The table is almost full; mark the end of the cached - * journal.*/ - *journal_table = __cpu_to_le32(0xffffffff); - journal_table = JOURNAL_END; - } - else - { - unsigned 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. - */ - - /* both are in the little endian format */ - *journal_table++ = desc.j_len; - for (i = 0; i < __le32_to_cpu(desc.j_len) && i < JOURNAL_TRANS_HALF; i++) - { - /* both are in the little endian format */ - *journal_table++ = desc.j_realblock[i]; -#ifdef REISERDEBUG - printf ("block %d is in journal %d.\n", - __le32_to_cpu(desc.j_realblock[i]), desc_block); -#endif - } - for ( ; i < __le32_to_cpu(desc.j_len); i++) - { - /* both are in the little endian format */ - *journal_table++ = commit.j_realblock[i-JOURNAL_TRANS_HALF]; -#ifdef REISERDEBUG - printf ("block %d is in journal %d.\n", - __le32_to_cpu(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", - __le32_to_cpu(desc.j_trans_id), __le32_to_cpu(desc.j_mount_id), desc_block); -#endif - - INFO->journal_transactions - = next_trans_id - __le32_to_cpu(header.j_last_flush_trans_id) - 1; - return errnum == 0; -} - -/* check filesystem types and read superblock into memory buffer */ -int -reiserfs_mount (unsigned part_length) -{ - struct reiserfs_super_block super; - int superblock = REISERFS_DISK_OFFSET_IN_BYTES >> SECTOR_BITS; - - if (part_length < superblock + (sizeof (super) >> SECTOR_BITS) - || ! reiserfs_devread (superblock, 0, sizeof (struct reiserfs_super_block), - (char *) &super) - || (substring (REISER3FS_SUPER_MAGIC_STRING, super.s_magic) > 0 - && 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 */ - sb_journal_block(&super) * sb_blocksize(&super) - <= 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) - || ! reiserfs_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; - - set_sb_blocksize(&super, REISERFS_OLD_BLOCKSIZE); - set_sb_journal_block(&super, 0); - set_sb_version(&super, 0); - } - } - - /* check the version number. */ - if (sb_version(&super) > REISERFS_MAX_SUPPORTED_VERSION) - return 0; - - INFO->version = sb_version(&super); - INFO->blocksize = sb_blocksize(&super); - INFO->fullblocksize_shift = log2 (sb_blocksize(&super)); - 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 (sb_blocksize(&super) < FSYSREISER_MIN_BLOCKSIZE - || sb_blocksize(&super) > FSYSREISER_MAX_BLOCKSIZE - || (SECTOR_SIZE << INFO->blocksize_shift) != sb_blocksize(&super)) - 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 (sb_journal_block(&super) != 0 && super.s_journal_dev == 0) - { - INFO->journal_block = sb_journal_block(&super); - INFO->journal_block_count = sb_journal_size(&super); - 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 (sb_root_block(&super), 0, INFO->blocksize, (char*) ROOT)) - return 0; - - INFO->tree_depth = __le16_to_cpu(BLOCKHEAD (ROOT)->blk_level); - -#ifdef REISERDEBUG - printf ("root read_in: block=%d, depth=%d\n", - sb_root_block(&super), 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 (__le16_to_cpu(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", - __le32_to_cpu(INFO->current_ih->ih_key.k_dir_id), - __le32_to_cpu(INFO->current_ih->ih_key.k_objectid), - __le32_to_cpu(INFO->current_ih->ih_key.u.v1.k_offset), - __le32_to_cpu(INFO->current_ih->ih_key.u.v1.k_uniqueness), - __le16_to_cpu(INFO->current_ih->ih_version)); -#endif /* REISERDEBUG */ - - if (ih == &ITEMHEAD[__le16_to_cpu(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 = __le16_to_cpu(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_block_number(&(DC (cache)[key_nr])), --depth); - if (! cache) - return 0; - } - while (depth > DISK_LEAF_NODE_LEVEL); - - ih = ITEMHEAD; - } - found: - INFO->current_ih = ih; - INFO->current_item = &LEAF[__le16_to_cpu(ih->ih_item_location)]; -#ifdef REISERDEBUG - printf (" new ih: key %d:%d:%d:%d version:%d\n", - __le32_to_cpu(INFO->current_ih->ih_key.k_dir_id), - __le32_to_cpu(INFO->current_ih->ih_key.k_objectid), - __le32_to_cpu(INFO->current_ih->ih_key.u.v1.k_offset), - __le32_to_cpu(INFO->current_ih->ih_key.u.v1.k_uniqueness), - __le16_to_cpu(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 = __le16_to_cpu(BLOCKHEAD (cache)->blk_nr_item); - - key = KEY (cache); - - for (i = 0; i < nr_item; i++) - { - if (__le32_to_cpu(key->k_dir_id) > dir_id - || (__le32_to_cpu(key->k_dir_id) == dir_id - && (__le32_to_cpu(key->k_objectid) > objectid - || (__le32_to_cpu(key->k_objectid) == objectid - && (__le32_to_cpu(key->u.v1.k_offset) - | __le32_to_cpu(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_block_number(&(DC (cache)[i])), --depth); - if (! cache) - return 0; - } - - /* cache == LEAF */ - nr_item = __le16_to_cpu(BLOCKHEAD (LEAF)->blk_nr_item); - ih = ITEMHEAD; - for (i = 0; i < nr_item; i++) - { - if (__le32_to_cpu(ih->ih_key.k_dir_id) == dir_id - && __le32_to_cpu(ih->ih_key.k_objectid) == objectid - && __le32_to_cpu(ih->ih_key.u.v1.k_offset) == 0 - && __le32_to_cpu(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[__le16_to_cpu(ih->ih_item_location)]; - return 1; - } - ih++; - } - errnum = ERR_FSYS_CORRUPT; - return 0; -} - -int -reiserfs_read (char *buf, unsigned 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=%Lx\n", - filepos, len, (__u64) IH_KEY_OFFSET (INFO->current_ih) - 1); -#endif /* REISERDEBUG */ - - if (__le32_to_cpu(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 (__le32_to_cpu(INFO->current_ih->ih_key.k_objectid) != INFO->fileinfo.k_objectid) { - break; - } - - offset = filepos - IH_KEY_OFFSET (INFO->current_ih) + 1; - blocksize = __le16_to_cpu(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; - - 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 = __le32_to_cpu(((__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; - - /* Journal is only for meta data. Data blocks can be read - * directly without using block_read - */ - reiserfs_devread (blocknr << INFO->blocksize_shift, - blk_offset, to_read, buf); - 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. - */ -static 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", - stat_data_v1(INFO->current_ih) ? sd_v1_mode((struct stat_data_v1 *) INFO->current_item) : - sd_v2_mode((struct stat_data *) (INFO->current_item)), - stat_data_v1(INFO->current_ih) ? sd_v1_size((struct stat_data_v1 *) INFO->current_item) : - sd_v2_size((struct stat_data *) INFO->current_item) - ); - -#endif /* REISERDEBUG */ - mode = stat_data_v1(INFO->current_ih) ? - sd_v1_mode((struct stat_data_v1 *) INFO->current_item) : - sd_v2_mode((struct stat_data *) INFO->current_item); - - /* If we've got a symbolic link, then chase it. */ - if (S_ISLNK (mode)) - { - unsigned int len; - if (++link_count > MAX_LINK_COUNT) - { - errnum = ERR_SYMLINK_LOOP; - return 0; - } - - /* Get the symlink size. */ - filemax = stat_data_v1(INFO->current_ih) ? - sd_v1_size((struct stat_data_v1 *) INFO->current_item) : - sd_v2_size((struct stat_data *) INFO->current_item); - - /* 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! */ - 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 = stat_data_v1(INFO->current_ih) ? - sd_v1_size((struct stat_data_v1 *) INFO->current_item) : - sd_v2_size((struct stat_data *) INFO->current_item); - 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", - __le32_to_cpu(INFO->current_ih->ih_key.k_dir_id), - __le32_to_cpu(INFO->current_ih->ih_key.k_objectid), - __le32_to_cpu(INFO->current_ih->ih_key.u.v1.k_offset), - __le32_to_cpu(INFO->current_ih->ih_key.u.v1.k_uniqueness), - __le16_to_cpu(INFO->current_ih->ih_version)); -#endif /* REISERDEBUG */ - - if (__le32_to_cpu(INFO->current_ih->ih_key.k_objectid) != objectid) - break; - - name_end = INFO->current_item + __le16_to_cpu(INFO->current_ih->ih_item_len); - de_head = (struct reiserfs_de_head *) INFO->current_item; - num_entries = __le16_to_cpu(INFO->current_ih->u.ih_entry_count); - while (num_entries > 0) - { - char *filename = INFO->current_item + deh_location(de_head); - char tmp = *name_end; - if ((deh_state(de_head) & 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) - { - char fn[PATH_MAX]; - struct fsys_reiser_info info_save; - - if (print_possibilities > 0) - print_possibilities = -print_possibilities; - *name_end = 0; - strcpy(fn, filename); - *name_end = tmp; - - /* If NAME is "." or "..", do not count it. */ - if (strcmp (fn, ".") != 0 && strcmp (fn, "..") != 0) { - memcpy(&info_save, INFO, sizeof(struct fsys_reiser_info)); - search_stat (deh_dir_id(de_head), deh_objectid(de_head)); - sd_print_item(INFO->current_ih, INFO->current_item); - printf(" %s\n", fn); - search_stat (dir_id, objectid); - memcpy(INFO, &info_save, sizeof(struct fsys_reiser_info)); - } - } - } - 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 = deh_dir_id(de_head); - objectid = deh_objectid(de_head); - } -} - -/* - * U-Boot interface functions - */ - -/* - * List given directory - * - * RETURN: 0 - OK, else grub_error_t errnum - */ -int -reiserfs_ls (char *dirname) -{ - char *dir_slash; - int res; - - errnum = 0; - dir_slash = malloc(strlen(dirname) + 1); - if (dir_slash == NULL) { - return ERR_NUMBER_OVERFLOW; - } - strcpy(dir_slash, dirname); - /* add "/" to the directory name */ - strcat(dir_slash, "/"); - - print_possibilities = 1; - res = reiserfs_dir (dir_slash); - free(dir_slash); - if (!res || errnum) { - return errnum; - } - - return 0; -} - -/* - * Open file for reading - * - * RETURN: >0 - OK, size of opened file - * <0 - ERROR -grub_error_t errnum - */ -int -reiserfs_open (char *filename) -{ - /* open the file */ - errnum = 0; - print_possibilities = 0; - if (!reiserfs_dir (filename) || errnum) { - return -errnum; - } - return filemax; -} - -#endif /* CFG_CMD_REISER */ diff --git a/fs/reiserfs/reiserfs_private.h b/fs/reiserfs/reiserfs_private.h deleted file mode 100644 index d0197cb804..0000000000 --- a/fs/reiserfs/reiserfs_private.h +++ /dev/null @@ -1,520 +0,0 @@ -/* - * Copyright 2000-2002 by Hans Reiser, licensing governed by reiserfs/README - * - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2000, 2001 Free Software Foundation, Inc. - * - * (C) Copyright 2003 - 2004 - * Sysgo AG, <www.elinos.com>, Pavel Bartusek <pba@sysgo.com> - * - * - * 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. - */ - -/* An implementation for the ReiserFS filesystem ported from GRUB. - * Some parts of this code (mainly the structures and defines) are - * from the original reiser fs code, as found in the linux kernel. - */ - -#ifndef __BYTE_ORDER -#if defined(__LITTLE_ENDIAN) && !defined(__BIG_ENDIAN) -#define __BYTE_ORDER __LITTLE_ENDIAN -#elif defined(__BIG_ENDIAN) && !defined(__LITTLE_ENDIAN) -#define __BYTE_ORDER __BIG_ENDIAN -#else -#error "unable to define __BYTE_ORDER" -#endif -#endif /* not __BYTE_ORDER */ - -#define FSYS_BUFLEN 0x8000 -#define FSYS_BUF fsys_buf - -/* 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 sb_root_block(sbp) (__le32_to_cpu((sbp)->s_root_block)) -#define sb_journal_block(sbp) (__le32_to_cpu((sbp)->s_journal_block)) -#define set_sb_journal_block(sbp,v) ((sbp)->s_journal_block = __cpu_to_le32(v)) -#define sb_journal_size(sbp) (__le32_to_cpu((sbp)->s_journal_size)) -#define sb_blocksize(sbp) (__le16_to_cpu((sbp)->s_blocksize)) -#define set_sb_blocksize(sbp,v) ((sbp)->s_blocksize = __cpu_to_le16(v)) -#define sb_version(sbp) (__le16_to_cpu((sbp)->s_version)) -#define set_sb_version(sbp,v) ((sbp)->s_version = __cpu_to_le16(v)) - - -#define REISERFS_MAX_SUPPORTED_VERSION 2 -#define REISERFS_SUPER_MAGIC_STRING "ReIsErFs" -#define REISER2FS_SUPER_MAGIC_STRING "ReIsEr2Fs" -#define REISER3FS_SUPER_MAGIC_STRING "ReIsEr3Fs" - -#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 - */ - -#if defined(__LITTLE_ENDIAN_BITFIELD) - /* little endian version */ - __u64 k_offset:60; - __u64 k_type: 4; -#elif defined(__BIG_ENDIAN_BITFIELD) - /* big endian version */ - __u64 k_type: 4; - __u64 k_offset:60; -#else -#error "__LITTLE_ENDIAN_BITFIELD or __BIG_ENDIAN_BITFIELD must be defined" -#endif -} __attribute__ ((__packed__)); - -#define TYPE_MAXTYPE 3 -#define TYPE_ANY 15 - -#if (__BYTE_ORDER == __BIG_ENDIAN) -typedef union { - struct offset_v2 offset_v2; - __u64 linear; -} __attribute__ ((__packed__)) offset_v2_esafe_overlay; - -static inline __u16 offset_v2_k_type( const struct offset_v2 *v2 ) -{ - offset_v2_esafe_overlay tmp = *(const offset_v2_esafe_overlay *)v2; - tmp.linear = __le64_to_cpu( tmp.linear ); - return (tmp.offset_v2.k_type <= TYPE_MAXTYPE)?tmp.offset_v2.k_type:TYPE_ANY; -} - -static inline loff_t offset_v2_k_offset( const struct offset_v2 *v2 ) -{ - offset_v2_esafe_overlay tmp = *(const offset_v2_esafe_overlay *)v2; - tmp.linear = __le64_to_cpu( tmp.linear ); - return tmp.offset_v2.k_offset; -} -#elif (__BYTE_ORDER == __LITTLE_ENDIAN) -# define offset_v2_k_type(v2) ((v2)->k_type) -# define offset_v2_k_offset(v2) ((v2)->k_offset) -#else -#error "__BYTE_ORDER must be __LITTLE_ENDIAN or __BIG_ENDIAN" -#endif - -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 -{ - /* Everything in the tree is found by searching for it based on - * its key.*/ - struct key ih_key; - union { - /* 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_free_space; - /* Iff this is a directory item, this field equals the - number of directory entries in the directory item. */ - __u16 ih_entry_count; - } __attribute__ ((__packed__)) 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; /* 0 for all old items, 2 for new - ones. Highest bit is set by fsck - temporary, cleaned after all - done */ -} __attribute__ ((__packed__)); - -/* size of item header */ -#define IH_SIZE (sizeof (struct item_head)) - -#define ITEM_VERSION_1 0 -#define ITEM_VERSION_2 1 - -#define ih_version(ih) (__le16_to_cpu((ih)->ih_version)) - -#define IH_KEY_OFFSET(ih) (ih_version(ih) == ITEM_VERSION_1 \ - ? __le32_to_cpu((ih)->ih_key.u.v1.k_offset) \ - : offset_v2_k_offset(&((ih)->ih_key.u.v2))) - -#define IH_KEY_ISTYPE(ih, type) (ih_version(ih) == ITEM_VERSION_1 \ - ? __le32_to_cpu((ih)->ih_key.u.v1.k_uniqueness) == V1_##type \ - : offset_v2_k_type(&((ih)->ih_key.u.v2)) == V2_##type) - -/***************************************************************************/ -/* DISK CHILD */ -/***************************************************************************/ -/* Disk child pointer: The pointer from an internal node of the tree - to a node that is on disk. */ -struct disk_child { - __u32 dc_block_number; /* Disk child's block number. */ - __u16 dc_size; /* Disk child's used space. */ - __u16 dc_reserved; -}; - -#define DC_SIZE (sizeof(struct disk_child)) -#define dc_block_number(dc_p) (__le32_to_cpu((dc_p)->dc_block_number)) - - -/* - * old stat data is 32 bytes long. We are going to distinguish new one by - * different size - */ -struct stat_data_v1 -{ - __u16 sd_mode; /* file type, permissions */ - __u16 sd_nlink; /* number of hard links */ - __u16 sd_uid; /* owner */ - __u16 sd_gid; /* group */ - __u32 sd_size; /* file size */ - __u32 sd_atime; /* time of last access */ - __u32 sd_mtime; /* time file was last modified */ - __u32 sd_ctime; /* time inode (stat data) was last changed (except changes to sd_atime and sd_mtime) */ - union { - __u32 sd_rdev; - __u32 sd_blocks; /* number of blocks file uses */ - } __attribute__ ((__packed__)) u; - __u32 sd_first_direct_byte; /* first byte of file which is stored - in a direct item: except that if it - equals 1 it is a symlink and if it - equals ~(__u32)0 there is no - direct item. The existence of this - field really grates on me. Let's - replace it with a macro based on - sd_size and our tail suppression - policy. Someday. -Hans */ -} __attribute__ ((__packed__)); - -#define stat_data_v1(ih) (ih_version(ih) == ITEM_VERSION_1) -#define sd_v1_mode(sdp) ((sdp)->sd_mode) -#define sd_v1_nlink(sdp) (__le16_to_cpu((sdp)->sd_nlink)) -#define sd_v1_uid(sdp) (__le16_to_cpu((sdp)->sd_uid)) -#define sd_v1_gid(sdp) (__le16_to_cpu((sdp)->sd_gid)) -#define sd_v1_size(sdp) (__le32_to_cpu((sdp)->sd_size)) -#define sd_v1_mtime(sdp) (__le32_to_cpu((sdp)->sd_mtime)) - -/* Stat Data on disk (reiserfs version of UFS disk inode minus the - address blocks) */ -struct stat_data { - __u16 sd_mode; /* file type, permissions */ - __u16 sd_attrs; /* persistent inode flags */ - __u32 sd_nlink; /* number of hard links */ - __u64 sd_size; /* file size */ - __u32 sd_uid; /* owner */ - __u32 sd_gid; /* group */ - __u32 sd_atime; /* time of last access */ - __u32 sd_mtime; /* time file was last modified */ - __u32 sd_ctime; /* time inode (stat data) was last changed (except changes to sd_atime and sd_mtime) */ - __u32 sd_blocks; - union { - __u32 sd_rdev; - __u32 sd_generation; - /*__u32 sd_first_direct_byte; */ - /* first byte of file which is stored in a - direct item: except that if it equals 1 - it is a symlink and if it equals - ~(__u32)0 there is no direct item. The - existence of this field really grates - on me. Let's replace it with a macro - based on sd_size and our tail - suppression policy? */ - } __attribute__ ((__packed__)) u; -} __attribute__ ((__packed__)); - -#define stat_data_v2(ih) (ih_version(ih) == ITEM_VERSION_2) -#define sd_v2_mode(sdp) (__le16_to_cpu((sdp)->sd_mode)) -#define sd_v2_nlink(sdp) (__le32_to_cpu((sdp)->sd_nlink)) -#define sd_v2_size(sdp) (__le64_to_cpu((sdp)->sd_size)) -#define sd_v2_uid(sdp) (__le32_to_cpu((sdp)->sd_uid)) -#define sd_v2_gid(sdp) (__le32_to_cpu((sdp)->sd_gid)) -#define sd_v2_mtime(sdp) (__le32_to_cpu((sdp)->sd_mtime)) - -#define sd_mode(sdp) (__le16_to_cpu((sdp)->sd_mode)) -#define sd_size(sdp) (__le32_to_cpu((sdp)->sd_size)) -#define sd_size_hi(sdp) (__le32_to_cpu((sdp)->sd_size_hi)) - -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_offset(p_deh) (__le32_to_cpu((p_deh)->deh_offset)) -#define deh_dir_id(p_deh) (__le32_to_cpu((p_deh)->deh_dir_id)) -#define deh_objectid(p_deh) (__le32_to_cpu((p_deh)->deh_objectid)) -#define deh_location(p_deh) (__le16_to_cpu((p_deh)->deh_location)) -#define deh_state(p_deh) (__le16_to_cpu((p_deh)->deh_state)) - - -#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) -{ -#ifdef __I386__ - __asm__ ("bsfl %1,%0" - : "=r" (word) - : "r" (word)); - return word; -#else - int i; - - for(i=0; i<(8*sizeof(word)); i++) - if ((1<<i) & word) - return i; - - return 0; -#endif -} - -static __inline__ int -is_power_of_two (unsigned long word) -{ - return (word & -word) == word; -} - -extern const char *bb_mode_string(int mode); -extern int reiserfs_devread (int sector, int byte_offset, int byte_len, char *buf); |