From 07d6fd513f1c4d3c6905c880948671de1181fac2 Mon Sep 17 00:00:00 2001 From: Chris Johns Date: Wed, 29 Apr 2009 08:31:27 +0000 Subject: 2009-04-29 Chris Johns * libcsupport/include/rtems/libio.h: Add rtems_off64_t for internal use. Update the internal off_t to the 64bit offset. * libnetworking/lib/ftpfs.c, libnetworking/lib/tftpDriver.c, libfs/src/nfsclient/src/nfs.c, libfs/src/imfs/imfs_fifo.c, libfs/src/imfs/memfile.c, libfs/src/imfs/imfs_directory.c, libfs/src/imfs/imfs.h, libfs/src/imfs/deviceio.c: Change off_t to rtems_off64_t. * libmisc/shell/main_msdosfmt.c: Add an info level so the format code can tell the user what is happening. Add more options to control the format configuration. * libfs/src/dosfs/msdos_format.c: Add a print function to display the format progress and print statements. Select a better default cluster size depending on the size of the disk. This lowers the size of the FAT on large disks. Read and maintain the MRB partition information. * libfs/src/dosfs/dosfs.h, libfs/src/dosfs/fat.h, libfs/src/dosfs/fat_file.c, libfs/src/dosfs/fat_file.h, libfs/src/dosfs/msdos.h, libfs/src/dosfs/msdos_conv.c, libfs/src/dosfs/msdos_create.c, libfs/src/dosfs/msdos_file.c, libfs/src/dosfs/msdos_handlers_dir.c, libfs/src/dosfs/msdos_handlers_file.c, libfs/src/dosfs/msdos_init.c, libfs/src/dosfs/msdos_initsupp.c, libfs/src/dosfs/msdos_misc.c, libfs/src/dosfs/msdos_mknod.c: Add long file name support. Change off_t to rtems_off64_t. --- cpukit/libfs/src/dosfs/msdos_format.c | 216 ++++++++++++++++++++++++++-------- 1 file changed, 169 insertions(+), 47 deletions(-) (limited to 'cpukit/libfs/src/dosfs/msdos_format.c') diff --git a/cpukit/libfs/src/dosfs/msdos_format.c b/cpukit/libfs/src/dosfs/msdos_format.c index 1d012c29f5..7e72b5e089 100644 --- a/cpukit/libfs/src/dosfs/msdos_format.c +++ b/cpukit/libfs/src/dosfs/msdos_format.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -65,6 +66,58 @@ typedef struct { uint32_t vol_id; } msdos_format_param_t; +/* + * Formatted output. + */ +static void +msdos_format_printf (const msdos_format_request_param_t *rqdata, + int info_level, + const char *format, ...) +{ + va_list args; + va_start (args, format); + if (rqdata->info_level >= info_level) + { + vfprintf (stdout, format, args); + fflush (stdout); + } +} + +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +static int msdos_format_read_sec +( +/*-------------------------------------------------------------------------*\ +| Purpose: | +| function to read a sector | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ + int fd, /* file descriptor index */ + uint32_t start_sector, /* sector number to write to */ + uint32_t sector_size, /* size of sector */ + char *buffer /* buffer with read data into */ + ) +/*-------------------------------------------------------------------------*\ +| Return Value: | +| 0, if success, -1 and errno if failed | +\*=========================================================================*/ +{ + int ret_val = 0; + + if (0 > lseek(fd,((off_t)start_sector)*sector_size,SEEK_SET)) { + ret_val = -1; + } + if (ret_val == 0) { + if (0 > read(fd,buffer,sector_size)) { + ret_val = -1; + } + } + + return ret_val; +} + /*=========================================================================*\ | Function: | \*-------------------------------------------------------------------------*/ @@ -100,7 +153,7 @@ static int msdos_format_write_sec return ret_val; } -/*=========================================================================*\ +/*=========================================================================* \ | Function: | \*-------------------------------------------------------------------------*/ static int msdos_format_fill_sectors @@ -111,6 +164,7 @@ static int msdos_format_fill_sectors +---------------------------------------------------------------------------+ | Input Parameters: | \*-------------------------------------------------------------------------*/ + const msdos_format_request_param_t *rqdata, int fd, /* file descriptor index */ uint32_t start_sector, /* sector number to fill to */ uint32_t sector_cnt, /* number of sectors to fill to */ @@ -124,7 +178,9 @@ static int msdos_format_fill_sectors { int ret_val = 0; char *fill_buffer = NULL; - + uint32_t total_sectors = sector_cnt; + int last_percent = -1; + /* * allocate and fill buffer */ @@ -138,15 +194,31 @@ static int msdos_format_fill_sectors memset(fill_buffer,fill_byte,sector_size); } } + + msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_DETAIL, + "Filling : "); /* * write to consecutive sectors */ while ((ret_val == 0) && (sector_cnt > 0)) { + int percent = (sector_cnt * 100) / total_sectors; + if (percent != last_percent) { + if ((percent & 1) == 0) + msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_DETAIL, "."); + last_percent = percent; + } ret_val = msdos_format_write_sec(fd,start_sector,sector_size,fill_buffer); start_sector++; sector_cnt--; } + + msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_DETAIL, "\n"); + + if (ret_val) + msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_INFO, + "filling error on sector: %d\n", start_sector); + /* * cleanup */ @@ -311,7 +383,8 @@ static int msdos_format_determine_fmt_params uint32_t fatdata_sect_cnt; uint32_t onebit; uint32_t sectors_per_cluster_adj = 0; - + uint64_t total_size = 0; + memset(fmt_params,0,sizeof(*fmt_params)); /* * this one is fixed in this implementation. @@ -320,6 +393,10 @@ static int msdos_format_determine_fmt_params if (ret_val == 0) { fmt_params->bytes_per_sector = dd->block_size; fmt_params->totl_sector_cnt = dd->size; + total_size = dd->block_size * dd->size; + msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_DETAIL, + "bytes per sector: %d\ntotal sectors: %d\ntotal size: %lu\n", + dd->block_size, dd->size, total_size); } /* * determine number of FATs @@ -336,6 +413,11 @@ static int msdos_format_determine_fmt_params ret_val = EINVAL; } } + + if (ret_val == 0) + msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_DETAIL, + "number of fats: %d\n", fmt_params->fat_num); + /* * Now we get sort of a loop when determining things: * The FAT type (FAT12/16/32) is determined ONLY from the @@ -396,21 +478,26 @@ static int msdos_format_determine_fmt_params * are a compromise concerning capacity and efficency */ if (fmt_params->totl_sector_cnt - < ((uint32_t)FAT_FAT12_MAX_CLN)*8) { - fmt_params->fattype = FAT_FAT12; - /* start trying with small clusters */ - fmt_params->sectors_per_cluster = 2; + < ((uint32_t)FAT_FAT12_MAX_CLN)*8) { + fmt_params->fattype = FAT_FAT12; + /* start trying with small clusters */ + fmt_params->sectors_per_cluster = 2; } else if (fmt_params->totl_sector_cnt - < ((uint32_t)FAT_FAT16_MAX_CLN)*32) { - fmt_params->fattype = FAT_FAT16; - /* start trying with small clusters */ - fmt_params->sectors_per_cluster = 2; + < ((uint32_t)FAT_FAT16_MAX_CLN)*32) { + fmt_params->fattype = FAT_FAT16; + /* start trying with small clusters */ + fmt_params->sectors_per_cluster = 2; } else { - fmt_params->fattype = FAT_FAT32; - /* start trying with small clusters... */ - fmt_params->sectors_per_cluster = 1; + uint32_t gigs = (total_size + (1024 * 1024 * 1024)) / (1024 * 1024 * 1024); + int b; + fmt_params->fattype = FAT_FAT32; + /* scale with the size of disk... */ + for (b = 31; b > 0; b--) + if ((gigs & (1 << b)) != 0) + break; + fmt_params->sectors_per_cluster = 1 << b; } } /* @@ -428,7 +515,7 @@ static int msdos_format_determine_fmt_params * sectors_per_cluster*bytes_per_sector must not be bigger than 32K */ for (onebit = 128;onebit >= 1;onebit = onebit>>1) { - if (fmt_params->sectors_per_cluster > onebit) { + if (fmt_params->sectors_per_cluster >= onebit) { fmt_params->sectors_per_cluster = onebit; if (fmt_params->sectors_per_cluster <= 32768L/fmt_params->bytes_per_sector) { @@ -440,6 +527,9 @@ static int msdos_format_determine_fmt_params } if (ret_val == 0) { + msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_DETAIL, + "sectors per cluster: %d\n", fmt_params->sectors_per_cluster); + if (fmt_params->fattype == FAT_FAT32) { /* recommended: for FAT32, always set reserved sector count to 32 */ fmt_params->rsvd_sector_cnt = 32; @@ -649,9 +739,15 @@ static int msdos_format_gen_mbr total_sectors_num32 = fmt_params->totl_sector_cnt; } /* - * finally we are there: let's fill in the values into the MBR + * finally we are there: let's fill in the values into the MBR + * but first clear the MRB leaving the partition table. */ - memset(mbr,0,FAT_TOTAL_MBR_SIZE); +#define RTEMS_IDE_PARTITION_TABLE_OFFSET 0x1be +#define RTEMS_IDE_PARTITION_TABLE_SIZE (4 * 16) + memset(mbr,0,RTEMS_IDE_PARTITION_TABLE_OFFSET); + memset(mbr + RTEMS_IDE_PARTITION_TABLE_OFFSET + RTEMS_IDE_PARTITION_TABLE_SIZE, + 0, + FAT_TOTAL_MBR_SIZE - (RTEMS_IDE_PARTITION_TABLE_OFFSET + RTEMS_IDE_PARTITION_TABLE_SIZE)); /* * FIXME: fill jmpBoot and Boot code... * with 0xEB,.... @@ -672,9 +768,9 @@ static int msdos_format_gen_mbr FAT_SET_BR_TOTAL_SECTORS_NUM16(mbr , total_sectors_num16); FAT_SET_BR_MEDIA(mbr , fmt_params->media_code); - FAT_SET_BR_SECTORS_PER_TRACK(mbr , 0); /* only needed for INT13... */ - FAT_SET_BR_NUMBER_OF_HEADS(mbr , 0); /* only needed for INT13... */ - FAT_SET_BR_HIDDEN_SECTORS(mbr , 0); /* only needed for INT13... */ + FAT_SET_BR_SECTORS_PER_TRACK(mbr , 255); /* only needed for INT13... */ + FAT_SET_BR_NUMBER_OF_HEADS(mbr , 6); /* only needed for INT13... */ + FAT_SET_BR_HIDDEN_SECTORS(mbr , 1); /* only needed for INT13... */ FAT_SET_BR_TOTAL_SECTORS_NUM32(mbr , total_sectors_num32); if (fmt_params->fattype != FAT_FAT32) { @@ -749,7 +845,6 @@ static int msdos_format_gen_fsinfo | 0, if success, -1 and errno if failed | \*=========================================================================*/ { - /* * clear fsinfo sector data */ @@ -760,9 +855,9 @@ static int msdos_format_gen_fsinfo FAT_SET_FSINFO_LEAD_SIGNATURE (fsinfo,FAT_FSINFO_LEAD_SIGNATURE_VALUE ); FAT_SET_FSINFO_STRUC_SIGNATURE(fsinfo,FAT_FSINFO_STRUC_SIGNATURE_VALUE); FAT_SET_FSINFO_TRAIL_SIGNATURE(fsinfo,FAT_FSINFO_TRAIL_SIGNATURE_VALUE); -/* - * write "empty" values for free cluster count and next cluster number - */ + /* + * write "empty" values for free cluster count and next cluster number + */ FAT_SET_FSINFO_FREE_CLUSTER_COUNT(fsinfo+FAT_FSI_INFO, 0xffffffff); FAT_SET_FSINFO_NEXT_FREE_CLUSTER (fsinfo+FAT_FSI_INFO, @@ -800,9 +895,13 @@ int msdos_format int i; msdos_format_param_t fmt_params; + msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_INFO, + "formating: %s\n", devname); /* * sanity check on device */ + msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_DETAIL, + "stat check: %s\n", devname); if (ret_val == 0) { rc = stat(devname, &stat_buf); ret_val = rc; @@ -828,7 +927,9 @@ int msdos_format * open device for writing */ if (ret_val == 0) { - fd = open(devname, O_WRONLY); + msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_DETAIL, + "open device\n"); + fd = open(devname, O_RDWR); if (fd == -1) { ret_val= -1; @@ -848,7 +949,8 @@ int msdos_format (rqdata != NULL) && !(rqdata->quick_format)) { ret_val = msdos_format_fill_sectors - (fd, + (rqdata, + fd, 0, /* start sector */ fmt_params.totl_sector_cnt, /* sector count */ fmt_params.bytes_per_sector, @@ -858,27 +960,45 @@ int msdos_format * create master boot record */ if (ret_val == 0) { - ret_val = msdos_format_gen_mbr(tmp_sec,&fmt_params); - } - /* - * write master boot record to disk - * also write copy of MBR to disk - */ - if (ret_val == 0) { - ret_val = msdos_format_write_sec(fd, - 0, - fmt_params.bytes_per_sector, - tmp_sec); - } - if ((ret_val == 0) && - (fmt_params.mbr_copy_sec != 0)) { /* - * write copy of MBR + * Read the current MBR to obtain the partition table. */ - ret_val = msdos_format_write_sec(fd, - fmt_params.mbr_copy_sec , - fmt_params.bytes_per_sector, - tmp_sec); + msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_DETAIL, + "read MRB sector\n"); + ret_val = msdos_format_read_sec(fd, + 0, + fmt_params.bytes_per_sector, + tmp_sec); + if (ret_val == 0) { + msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_DETAIL, + "generate MRB sector\n"); + ret_val = msdos_format_gen_mbr(tmp_sec,&fmt_params); + } + + /* + * write master boot record to disk + * also write copy of MBR to disk + */ + if (ret_val == 0) { + msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_DETAIL, + "write MRB sector\n"); + ret_val = msdos_format_write_sec(fd, + 0, + fmt_params.bytes_per_sector, + tmp_sec); + } + if ((ret_val == 0) && + (fmt_params.mbr_copy_sec != 0)) { + /* + * write copy of MBR + */ + msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_DETAIL, + "write back up MRB sector\n"); + ret_val = msdos_format_write_sec(fd, + fmt_params.mbr_copy_sec , + fmt_params.bytes_per_sector, + tmp_sec); + } } /* * for FAT32: initialize info sector on disk @@ -903,7 +1023,8 @@ int msdos_format */ if (ret_val == 0) { ret_val = msdos_format_fill_sectors - (fd, + (rqdata, + fd, fmt_params.rsvd_sector_cnt, /* start sector */ fmt_params.fat_num*fmt_params.sectors_per_fat,/* sector count */ fmt_params.bytes_per_sector, @@ -915,7 +1036,8 @@ int msdos_format */ if (ret_val == 0) { ret_val = msdos_format_fill_sectors - (fd, + (rqdata, + fd, fmt_params.root_dir_start_sec, /* start sector */ fmt_params.root_dir_fmt_sec_cnt, /* sector count */ fmt_params.bytes_per_sector, -- cgit v1.2.3