summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/ext4/dev.c32
-rw-r--r--fs/ext4/ext4_common.h1
-rw-r--r--fs/ext4/ext4fs.c37
-rw-r--r--fs/fat/fat.c98
-rw-r--r--fs/fat/fat_write.c18
-rw-r--r--fs/reiserfs/dev.c29
-rw-r--r--fs/zfs/dev.c35
7 files changed, 124 insertions, 126 deletions
diff --git a/fs/ext4/dev.c b/fs/ext4/dev.c
index 9e85228ed..1596a92b9 100644
--- a/fs/ext4/dev.c
+++ b/fs/ext4/dev.c
@@ -38,26 +38,20 @@
#include <common.h>
#include <config.h>
+#include <ext4fs.h>
#include <ext_common.h>
+unsigned long part_offset;
+
static block_dev_desc_t *ext4fs_block_dev_desc;
-static disk_partition_t part_info;
+static disk_partition_t *part_info;
-int ext4fs_set_blk_dev(block_dev_desc_t *rbdd, int part)
+void ext4fs_set_blk_dev(block_dev_desc_t *rbdd, disk_partition_t *info)
{
ext4fs_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(ext4fs_block_dev_desc,
- part, &part_info))
- return 0;
- }
- return part_info.size;
+ part_info = info;
+ part_offset = info->start;
+ get_fs()->total_sect = (info->size * info->blksz) / SECTOR_SIZE;
}
int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf)
@@ -68,7 +62,7 @@ int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf)
/* Check partition boundaries */
if ((sector < 0)
|| ((sector + ((byte_offset + byte_len - 1) >> SECTOR_BITS)) >=
- part_info.size)) {
+ part_info->size)) {
printf("%s read outside partition %d\n", __func__, sector);
return 0;
}
@@ -88,7 +82,7 @@ int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf)
/* read first part which isn't aligned with start of sector */
if (ext4fs_block_dev_desc->
block_read(ext4fs_block_dev_desc->dev,
- part_info.start + sector, 1,
+ part_info->start + sector, 1,
(unsigned long *) sec_buf) != 1) {
printf(" ** ext2fs_devread() read error **\n");
return 0;
@@ -111,14 +105,14 @@ int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf)
block_len = SECTOR_SIZE;
ext4fs_block_dev_desc->block_read(ext4fs_block_dev_desc->dev,
- part_info.start + sector,
+ part_info->start + sector,
1, (unsigned long *)p);
memcpy(buf, p, byte_len);
return 1;
}
if (ext4fs_block_dev_desc->block_read(ext4fs_block_dev_desc->dev,
- part_info.start + sector,
+ part_info->start + sector,
block_len / SECTOR_SIZE,
(unsigned long *) buf) !=
block_len / SECTOR_SIZE) {
@@ -134,7 +128,7 @@ int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf)
/* read rest of data which are not in whole sector */
if (ext4fs_block_dev_desc->
block_read(ext4fs_block_dev_desc->dev,
- part_info.start + sector, 1,
+ part_info->start + sector, 1,
(unsigned long *) sec_buf) != 1) {
printf("* %s read error - last part\n", __func__);
return 0;
diff --git a/fs/ext4/ext4_common.h b/fs/ext4/ext4_common.h
index 0af625db2..f72813418 100644
--- a/fs/ext4/ext4_common.h
+++ b/fs/ext4/ext4_common.h
@@ -62,7 +62,6 @@ static inline void *zalloc(size_t size)
return p;
}
-extern unsigned long part_offset;
int ext4fs_read_inode(struct ext2_data *data, int ino,
struct ext2_inode *inode);
int ext4fs_read_file(struct ext2fs_node *node, int pos,
diff --git a/fs/ext4/ext4fs.c b/fs/ext4/ext4fs.c
index 114c2a214..93dcb7e8f 100644
--- a/fs/ext4/ext4fs.c
+++ b/fs/ext4/ext4fs.c
@@ -43,44 +43,11 @@
#include "ext4_common.h"
int ext4fs_symlinknest;
-block_dev_desc_t *ext4_dev_desc;
+struct ext_filesystem ext_fs;
struct ext_filesystem *get_fs(void)
{
- if (ext4_dev_desc == NULL || ext4_dev_desc->priv == NULL)
- printf("Invalid Input Arguments %s\n", __func__);
-
- return ext4_dev_desc->priv;
-}
-
-int init_fs(block_dev_desc_t *dev_desc)
-{
- struct ext_filesystem *fs;
- if (dev_desc == NULL) {
- printf("Invalid Input Arguments %s\n", __func__);
- return -EINVAL;
- }
-
- fs = zalloc(sizeof(struct ext_filesystem));
- if (fs == NULL) {
- printf("malloc failed: %s\n", __func__);
- return -ENOMEM;
- }
-
- fs->dev_desc = dev_desc;
- dev_desc->priv = fs;
-
- return 0;
-}
-
-void deinit_fs(block_dev_desc_t *dev_desc)
-{
- if (dev_desc == NULL) {
- printf("Invalid Input Arguments %s\n", __func__);
- return;
- }
- free(dev_desc->priv);
- dev_desc->priv = NULL;
+ return &ext_fs;
}
void ext4fs_free_node(struct ext2fs_node *node, struct ext2fs_node *currroot)
diff --git a/fs/fat/fat.c b/fs/fat/fat.c
index 19f6a8c0a..41ae15eeb 100644
--- a/fs/fat/fat.c
+++ b/fs/fat/fat.c
@@ -328,13 +328,16 @@ get_cluster(fsdata *mydata, __u32 clustnum, __u8 *buffer, unsigned long size)
}
/*
- * Read at most 'maxsize' bytes from the file associated with 'dentptr'
+ * Read at most 'maxsize' bytes from 'pos' in the file associated with 'dentptr'
* into 'buffer'.
* Return the number of bytes read or -1 on fatal errors.
*/
+__u8 get_contents_vfatname_block[MAX_CLUSTSIZE]
+ __aligned(ARCH_DMA_MINALIGN);
+
static long
-get_contents(fsdata *mydata, dir_entry *dentptr, __u8 *buffer,
- unsigned long maxsize)
+get_contents(fsdata *mydata, dir_entry *dentptr, unsigned long pos,
+ __u8 *buffer, unsigned long maxsize)
{
unsigned long filesize = FAT2CPU32(dentptr->size), gotsize = 0;
unsigned int bytesperclust = mydata->clust_size * mydata->sect_size;
@@ -344,12 +347,59 @@ get_contents(fsdata *mydata, dir_entry *dentptr, __u8 *buffer,
debug("Filesize: %ld bytes\n", filesize);
- if (maxsize > 0 && filesize > maxsize)
- filesize = maxsize;
+ if (pos >= filesize) {
+ debug("Read position past EOF: %lu\n", pos);
+ return gotsize;
+ }
+
+ if (maxsize > 0 && filesize > pos + maxsize)
+ filesize = pos + maxsize;
debug("%ld bytes\n", filesize);
actsize = bytesperclust;
+
+ /* go to cluster at pos */
+ while (actsize <= pos) {
+ curclust = get_fatent(mydata, curclust);
+ if (CHECK_CLUST(curclust, mydata->fatsize)) {
+ debug("curclust: 0x%x\n", curclust);
+ debug("Invalid FAT entry\n");
+ return gotsize;
+ }
+ actsize += bytesperclust;
+ }
+
+ /* actsize > pos */
+ actsize -= bytesperclust;
+ filesize -= actsize;
+ pos -= actsize;
+
+ /* align to beginning of next cluster if any */
+ if (pos) {
+ actsize = min(filesize, bytesperclust);
+ if (get_cluster(mydata, curclust, get_contents_vfatname_block,
+ (int)actsize) != 0) {
+ printf("Error reading cluster\n");
+ return -1;
+ }
+ filesize -= actsize;
+ actsize -= pos;
+ memcpy(buffer, get_contents_vfatname_block + pos, actsize);
+ gotsize += actsize;
+ if (!filesize)
+ return gotsize;
+ buffer += actsize;
+
+ curclust = get_fatent(mydata, curclust);
+ if (CHECK_CLUST(curclust, mydata->fatsize)) {
+ debug("curclust: 0x%x\n", curclust);
+ debug("Invalid FAT entry\n");
+ return gotsize;
+ }
+ }
+
+ actsize = bytesperclust;
endclust = curclust;
do {
@@ -433,9 +483,6 @@ static int slot2str(dir_slot *slotptr, char *l_name, int *idx)
* into 'retdent'
* Return 0 on success, -1 otherwise.
*/
-__u8 get_vfatname_block[MAX_CLUSTSIZE]
- __aligned(ARCH_DMA_MINALIGN);
-
static int
get_vfatname(fsdata *mydata, int curclust, __u8 *cluster,
dir_entry *retdent, char *l_name)
@@ -474,13 +521,13 @@ get_vfatname(fsdata *mydata, int curclust, __u8 *cluster,
return -1;
}
- if (get_cluster(mydata, curclust, get_vfatname_block,
+ if (get_cluster(mydata, curclust, get_contents_vfatname_block,
mydata->clust_size * mydata->sect_size) != 0) {
debug("Error: reading directory block\n");
return -1;
}
- slotptr2 = (dir_slot *)get_vfatname_block;
+ slotptr2 = (dir_slot *)get_contents_vfatname_block;
while (counter > 0) {
if (((slotptr2->id & ~LAST_LONG_ENTRY_MASK)
& 0xff) != counter)
@@ -491,7 +538,7 @@ get_vfatname(fsdata *mydata, int curclust, __u8 *cluster,
/* Save the real directory entry */
realdent = (dir_entry *)slotptr2;
- while ((__u8 *)slotptr2 > get_vfatname_block) {
+ while ((__u8 *)slotptr2 > get_contents_vfatname_block) {
slotptr2--;
slot2str(slotptr2, l_name, &idx);
}
@@ -770,11 +817,12 @@ exit:
return ret;
}
-__u8 do_fat_read_block[MAX_CLUSTSIZE]
+__u8 do_fat_read_at_block[MAX_CLUSTSIZE]
__aligned(ARCH_DMA_MINALIGN);
long
-do_fat_read(const char *filename, void *buffer, unsigned long maxsize, int dols)
+do_fat_read_at(const char *filename, unsigned long pos, void *buffer,
+ unsigned long maxsize, int dols)
{
char fnamecopy[2048];
boot_sector bs;
@@ -888,12 +936,12 @@ do_fat_read(const char *filename, void *buffer, unsigned long maxsize, int dols)
(mydata->fatsize == 32) ?
(mydata->clust_size) :
PREFETCH_BLOCKS,
- do_fat_read_block) < 0) {
+ do_fat_read_at_block) < 0) {
debug("Error: reading rootdir block\n");
goto exit;
}
- dentptr = (dir_entry *) do_fat_read_block;
+ dentptr = (dir_entry *) do_fat_read_at_block;
}
for (i = 0; i < DIRENTSPERBLOCK; i++) {
@@ -913,7 +961,7 @@ do_fat_read(const char *filename, void *buffer, unsigned long maxsize, int dols)
get_vfatname(mydata,
root_cluster,
- do_fat_read_block,
+ do_fat_read_at_block,
dentptr, l_name);
if (dols == LS_ROOT) {
@@ -1116,7 +1164,7 @@ rootdir_done:
subname = nextname;
}
- ret = get_contents(mydata, dentptr, buffer, maxsize);
+ ret = get_contents(mydata, dentptr, pos, buffer, maxsize);
debug("Size: %d, got: %ld\n", FAT2CPU32(dentptr->size), ret);
exit:
@@ -1124,6 +1172,12 @@ exit:
return ret;
}
+long
+do_fat_read(const char *filename, void *buffer, unsigned long maxsize, int dols)
+{
+ return do_fat_read_at(filename, 0, buffer, maxsize, dols);
+}
+
int file_fat_detectfs(void)
{
boot_sector bs;
@@ -1192,8 +1246,14 @@ 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)
+long file_fat_read_at(const char *filename, unsigned long pos, void *buffer,
+ unsigned long maxsize)
{
printf("reading %s\n", filename);
- return do_fat_read(filename, buffer, maxsize, LS_NO);
+ return do_fat_read_at(filename, pos, buffer, maxsize, LS_NO);
+}
+
+long file_fat_read(const char *filename, void *buffer, unsigned long maxsize)
+{
+ return file_fat_read_at(filename, 0, buffer, maxsize);
}
diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c
index a6181e71b..5829adf1a 100644
--- a/fs/fat/fat_write.c
+++ b/fs/fat/fat_write.c
@@ -328,7 +328,7 @@ static void flush_dir_table(fsdata *mydata, dir_entry **dentptr);
static void
fill_dir_slot(fsdata *mydata, dir_entry **dentptr, const char *l_name)
{
- dir_slot *slotptr = (dir_slot *)get_vfatname_block;
+ dir_slot *slotptr = (dir_slot *)get_contents_vfatname_block;
__u8 counter = 0, checksum;
int idx = 0, ret;
char s_name[16];
@@ -373,7 +373,7 @@ static __u32 dir_curclust;
* a slot) into 'l_name'. If successful also copy the real directory entry
* into 'retdent'
* If additional adjacent cluster for directory entries is read into memory,
- * then 'get_vfatname_block' is copied into 'get_dentfromdir_block' and
+ * then 'get_contents_vfatname_block' is copied into 'get_dentfromdir_block' and
* the location of the real directory entry is returned by 'retdent'
* Return 0 on success, -1 otherwise.
*/
@@ -416,13 +416,13 @@ get_long_file_name(fsdata *mydata, int curclust, __u8 *cluster,
dir_curclust = curclust;
- if (get_cluster(mydata, curclust, get_vfatname_block,
+ if (get_cluster(mydata, curclust, get_contents_vfatname_block,
mydata->clust_size * mydata->sect_size) != 0) {
debug("Error: reading directory block\n");
return -1;
}
- slotptr2 = (dir_slot *)get_vfatname_block;
+ slotptr2 = (dir_slot *)get_contents_vfatname_block;
while (counter > 0) {
if (((slotptr2->id & ~LAST_LONG_ENTRY_MASK)
& 0xff) != counter)
@@ -433,7 +433,7 @@ get_long_file_name(fsdata *mydata, int curclust, __u8 *cluster,
/* Save the real directory entry */
realdent = (dir_entry *)slotptr2;
- while ((__u8 *)slotptr2 > get_vfatname_block) {
+ while ((__u8 *)slotptr2 > get_contents_vfatname_block) {
slotptr2--;
slot2str(slotptr2, l_name, &idx);
}
@@ -459,9 +459,9 @@ get_long_file_name(fsdata *mydata, int curclust, __u8 *cluster,
*retdent = realdent;
if (slotptr2) {
- memcpy(get_dentfromdir_block, get_vfatname_block,
+ memcpy(get_dentfromdir_block, get_contents_vfatname_block,
mydata->clust_size * mydata->sect_size);
- cur_position = (__u8 *)realdent - get_vfatname_block;
+ cur_position = (__u8 *)realdent - get_contents_vfatname_block;
*retdent = (dir_entry *) &get_dentfromdir_block[cur_position];
}
@@ -980,11 +980,11 @@ static int do_fat_write(const char *filename, void *buffer,
if (disk_read(cursect,
(mydata->fatsize == 32) ?
(mydata->clust_size) :
- PREFETCH_BLOCKS, do_fat_read_block) < 0) {
+ PREFETCH_BLOCKS, do_fat_read_at_block) < 0) {
debug("Error: reading rootdir block\n");
goto exit;
}
- dentptr = (dir_entry *) do_fat_read_block;
+ dentptr = (dir_entry *) do_fat_read_at_block;
name_len = strlen(filename);
if (name_len >= VFAT_MAXLEN_BYTES)
diff --git a/fs/reiserfs/dev.c b/fs/reiserfs/dev.c
index 1facfaf18..cb288d60f 100644
--- a/fs/reiserfs/dev.c
+++ b/fs/reiserfs/dev.c
@@ -25,24 +25,13 @@
#include "reiserfs_private.h"
static block_dev_desc_t *reiserfs_block_dev_desc;
-static disk_partition_t part_info;
+static disk_partition_t *part_info;
-int reiserfs_set_blk_dev(block_dev_desc_t *rbdd, int part)
+void reiserfs_set_blk_dev(block_dev_desc_t *rbdd, disk_partition_t *info)
{
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);
+ part_info = info;
}
@@ -59,7 +48,7 @@ int reiserfs_devread (int sector, int byte_offset, int byte_len, char *buf)
*/
if (sector < 0
|| ((sector + ((byte_offset + byte_len - 1) >> SECTOR_BITS))
- >= part_info.size)) {
+ >= part_info->size)) {
/* errnum = ERR_OUTSIDE_PART; */
printf (" ** reiserfs_devread() read outside partition\n");
return 0;
@@ -83,7 +72,8 @@ int reiserfs_devread (int sector, int byte_offset, int byte_len, char *buf)
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) {
+ part_info->start + sector, 1,
+ (unsigned long *)sec_buf) != 1) {
printf (" ** reiserfs_devread() read error\n");
return 0;
}
@@ -96,8 +86,8 @@ int reiserfs_devread (int sector, int byte_offset, int byte_len, char *buf)
/* 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) {
+ part_info->start + sector, block_len/SECTOR_SIZE,
+ (unsigned long *)buf) != block_len/SECTOR_SIZE) {
printf (" ** reiserfs_devread() read error - block\n");
return 0;
}
@@ -108,7 +98,8 @@ int reiserfs_devread (int sector, int byte_offset, int byte_len, char *buf)
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) {
+ part_info->start + sector, 1,
+ (unsigned long *)sec_buf) != 1) {
printf (" ** reiserfs_devread() read error - last part\n");
return 0;
}
diff --git a/fs/zfs/dev.c b/fs/zfs/dev.c
index d68372c80..36be8f5c8 100644
--- a/fs/zfs/dev.c
+++ b/fs/zfs/dev.c
@@ -26,23 +26,12 @@
#include <zfs_common.h>
static block_dev_desc_t *zfs_block_dev_desc;
-static disk_partition_t part_info;
+static disk_partition_t *part_info;
-int zfs_set_blk_dev(block_dev_desc_t *rbdd, int part)
+void zfs_set_blk_dev(block_dev_desc_t *rbdd, disk_partition_t *info)
{
zfs_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(zfs_block_dev_desc, part, &part_info))
- return 0;
- }
-
- return part_info.size;
+ part_info = info;
}
/* err */
@@ -57,7 +46,7 @@ int zfs_devread(int sector, int byte_offset, int byte_len, char *buf)
*/
if ((sector < 0) ||
((sector + ((byte_offset + byte_len - 1) >> SECTOR_BITS)) >=
- part_info.size)) {
+ part_info->size)) {
/* errnum = ERR_OUTSIDE_PART; */
printf(" ** zfs_devread() read outside partition sector %d\n", sector);
return 1;
@@ -79,8 +68,8 @@ int zfs_devread(int sector, int byte_offset, int byte_len, char *buf)
if (byte_offset != 0) {
/* read first part which isn't aligned with start of sector */
if (zfs_block_dev_desc->block_read(zfs_block_dev_desc->dev,
- part_info.start + sector, 1,
- (unsigned long *) sec_buf) != 1) {
+ part_info->start + sector, 1,
+ (unsigned long *)sec_buf) != 1) {
printf(" ** zfs_devread() read error **\n");
return 1;
}
@@ -102,17 +91,15 @@ int zfs_devread(int sector, int byte_offset, int byte_len, char *buf)
block_len = SECTOR_SIZE;
zfs_block_dev_desc->block_read(zfs_block_dev_desc->dev,
- part_info.start + sector,
- 1, (unsigned long *)p);
+ part_info->start + sector,
+ 1, (unsigned long *)p);
memcpy(buf, p, byte_len);
return 0;
}
if (zfs_block_dev_desc->block_read(zfs_block_dev_desc->dev,
- part_info.start + sector,
- block_len / SECTOR_SIZE,
- (unsigned long *) buf) !=
- block_len / SECTOR_SIZE) {
+ part_info->start + sector, block_len / SECTOR_SIZE,
+ (unsigned long *) buf) != block_len / SECTOR_SIZE) {
printf(" ** zfs_devread() read error - block\n");
return 1;
}
@@ -126,7 +113,7 @@ int zfs_devread(int sector, int byte_offset, int byte_len, char *buf)
/* read rest of data which are not in whole sector */
if (zfs_block_dev_desc->
block_read(zfs_block_dev_desc->dev,
- part_info.start + sector, 1,
+ part_info->start + sector, 1,
(unsigned long *) sec_buf) != 1) {
printf(" ** zfs_devread() read error - last part\n");
return 1;