diff options
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/ext4/dev.c | 32 | ||||
| -rw-r--r-- | fs/ext4/ext4_common.h | 1 | ||||
| -rw-r--r-- | fs/ext4/ext4fs.c | 37 | ||||
| -rw-r--r-- | fs/fat/fat.c | 98 | ||||
| -rw-r--r-- | fs/fat/fat_write.c | 18 | ||||
| -rw-r--r-- | fs/reiserfs/dev.c | 29 | ||||
| -rw-r--r-- | fs/zfs/dev.c | 35 | 
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; |