forked from Imagelibrary/rtems
dosfs: Block size optimization
Change block size of bdbuf to the cluster size if the data clusters are aligned on a cluster boundary. This enables fast access to data clusters.
This commit is contained in:
committed by
Sebastian Huber
parent
5877a10fe2
commit
a20fbe78ec
@@ -17,88 +17,54 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#include <rtems/libio_.h>
|
#include <rtems/libio_.h>
|
||||||
|
|
||||||
#include "fat.h"
|
#include "fat.h"
|
||||||
#include "fat_fat_operations.h"
|
#include "fat_fat_operations.h"
|
||||||
|
|
||||||
|
static int
|
||||||
|
_fat_block_release(fat_fs_info_t *fs_info);
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
fat_cluster_read(fat_fs_info_t *fs_info,
|
||||||
|
uint32_t cln,
|
||||||
|
void *buff);
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
fat_cluster_write(fat_fs_info_t *fs_info,
|
||||||
|
uint32_t cln,
|
||||||
|
const void *buff);
|
||||||
|
|
||||||
int
|
int
|
||||||
fat_buf_access(fat_fs_info_t *fs_info, uint32_t blk, int op_type,
|
fat_buf_access(fat_fs_info_t *fs_info,
|
||||||
rtems_bdbuf_buffer **buf)
|
const uint32_t sec_num,
|
||||||
|
const int op_type,
|
||||||
|
uint8_t **sec_buf)
|
||||||
{
|
{
|
||||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||||
uint8_t i;
|
uint32_t blk = fat_sector_num_to_block_num (fs_info,
|
||||||
bool sec_of_fat;
|
sec_num);
|
||||||
|
uint32_t blk_ofs = fat_sector_offset_to_block_offset (fs_info,
|
||||||
|
sec_num,
|
||||||
|
0);
|
||||||
|
|
||||||
|
if (fs_info->c.state == FAT_CACHE_EMPTY || fs_info->c.blk_num != sec_num)
|
||||||
if (fs_info->c.state == FAT_CACHE_EMPTY)
|
|
||||||
{
|
{
|
||||||
|
fat_buf_release(fs_info);
|
||||||
|
|
||||||
if (op_type == FAT_OP_TYPE_READ)
|
if (op_type == FAT_OP_TYPE_READ)
|
||||||
sc = rtems_bdbuf_read(fs_info->vol.dd, blk, &fs_info->c.buf);
|
sc = rtems_bdbuf_read(fs_info->vol.dd, blk, &fs_info->c.buf);
|
||||||
else
|
else
|
||||||
sc = rtems_bdbuf_get(fs_info->vol.dd, blk, &fs_info->c.buf);
|
sc = rtems_bdbuf_get(fs_info->vol.dd, blk, &fs_info->c.buf);
|
||||||
if (sc != RTEMS_SUCCESSFUL)
|
if (sc != RTEMS_SUCCESSFUL)
|
||||||
rtems_set_errno_and_return_minus_one(EIO);
|
rtems_set_errno_and_return_minus_one(EIO);
|
||||||
fs_info->c.blk_num = blk;
|
fs_info->c.blk_num = sec_num;
|
||||||
fs_info->c.modified = 0;
|
fs_info->c.modified = 0;
|
||||||
fs_info->c.state = FAT_CACHE_ACTUAL;
|
fs_info->c.state = FAT_CACHE_ACTUAL;
|
||||||
}
|
}
|
||||||
|
*sec_buf = &fs_info->c.buf->buffer[blk_ofs];
|
||||||
sec_of_fat = ((fs_info->c.blk_num >= fs_info->vol.fat_loc) &&
|
|
||||||
(fs_info->c.blk_num < fs_info->vol.rdir_loc));
|
|
||||||
|
|
||||||
if (fs_info->c.blk_num != blk)
|
|
||||||
{
|
|
||||||
if (fs_info->c.modified)
|
|
||||||
{
|
|
||||||
if (sec_of_fat && !fs_info->vol.mirror)
|
|
||||||
memcpy(fs_info->sec_buf, fs_info->c.buf->buffer,
|
|
||||||
fs_info->vol.bps);
|
|
||||||
|
|
||||||
sc = rtems_bdbuf_release_modified(fs_info->c.buf);
|
|
||||||
fs_info->c.state = FAT_CACHE_EMPTY;
|
|
||||||
fs_info->c.modified = 0;
|
|
||||||
if (sc != RTEMS_SUCCESSFUL)
|
|
||||||
rtems_set_errno_and_return_minus_one(EIO);
|
|
||||||
|
|
||||||
if (sec_of_fat && !fs_info->vol.mirror)
|
|
||||||
{
|
|
||||||
rtems_bdbuf_buffer *b;
|
|
||||||
|
|
||||||
for (i = 1; i < fs_info->vol.fats; i++)
|
|
||||||
{
|
|
||||||
sc = rtems_bdbuf_get(fs_info->vol.dd,
|
|
||||||
fs_info->c.blk_num +
|
|
||||||
fs_info->vol.fat_length * i,
|
|
||||||
&b);
|
|
||||||
if ( sc != RTEMS_SUCCESSFUL)
|
|
||||||
rtems_set_errno_and_return_minus_one(ENOMEM);
|
|
||||||
memcpy(b->buffer, fs_info->sec_buf, fs_info->vol.bps);
|
|
||||||
sc = rtems_bdbuf_release_modified(b);
|
|
||||||
if ( sc != RTEMS_SUCCESSFUL)
|
|
||||||
rtems_set_errno_and_return_minus_one(ENOMEM);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sc = rtems_bdbuf_release(fs_info->c.buf);
|
|
||||||
fs_info->c.state = FAT_CACHE_EMPTY;
|
|
||||||
if (sc != RTEMS_SUCCESSFUL)
|
|
||||||
rtems_set_errno_and_return_minus_one(EIO);
|
|
||||||
|
|
||||||
}
|
|
||||||
if (op_type == FAT_OP_TYPE_READ)
|
|
||||||
sc = rtems_bdbuf_read(fs_info->vol.dd, blk, &fs_info->c.buf);
|
|
||||||
else
|
|
||||||
sc = rtems_bdbuf_get(fs_info->vol.dd, blk, &fs_info->c.buf);
|
|
||||||
if (sc != RTEMS_SUCCESSFUL)
|
|
||||||
rtems_set_errno_and_return_minus_one(EIO);
|
|
||||||
fs_info->c.blk_num = blk;
|
|
||||||
fs_info->c.state = FAT_CACHE_ACTUAL;
|
|
||||||
}
|
|
||||||
*buf = fs_info->c.buf;
|
|
||||||
return RC_OK;
|
return RC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,19 +72,24 @@ int
|
|||||||
fat_buf_release(fat_fs_info_t *fs_info)
|
fat_buf_release(fat_fs_info_t *fs_info)
|
||||||
{
|
{
|
||||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||||
uint8_t i;
|
|
||||||
bool sec_of_fat;
|
|
||||||
|
|
||||||
if (fs_info->c.state == FAT_CACHE_EMPTY)
|
if (fs_info->c.state == FAT_CACHE_EMPTY)
|
||||||
return RC_OK;
|
return RC_OK;
|
||||||
|
|
||||||
sec_of_fat = ((fs_info->c.blk_num >= fs_info->vol.fat_loc) &&
|
|
||||||
(fs_info->c.blk_num < fs_info->vol.rdir_loc));
|
|
||||||
|
|
||||||
if (fs_info->c.modified)
|
if (fs_info->c.modified)
|
||||||
{
|
{
|
||||||
|
uint32_t sec_num = fs_info->c.blk_num;
|
||||||
|
bool sec_of_fat = ((sec_num >= fs_info->vol.fat_loc) &&
|
||||||
|
(sec_num < fs_info->vol.rdir_loc));
|
||||||
|
uint32_t blk = fat_sector_num_to_block_num(fs_info, sec_num);
|
||||||
|
uint32_t blk_ofs = fat_sector_offset_to_block_offset(fs_info,
|
||||||
|
sec_num,
|
||||||
|
0);
|
||||||
|
|
||||||
if (sec_of_fat && !fs_info->vol.mirror)
|
if (sec_of_fat && !fs_info->vol.mirror)
|
||||||
memcpy(fs_info->sec_buf, fs_info->c.buf->buffer, fs_info->vol.bps);
|
memcpy(fs_info->sec_buf,
|
||||||
|
fs_info->c.buf->buffer + blk_ofs,
|
||||||
|
fs_info->vol.bps);
|
||||||
|
|
||||||
sc = rtems_bdbuf_release_modified(fs_info->c.buf);
|
sc = rtems_bdbuf_release_modified(fs_info->c.buf);
|
||||||
if (sc != RTEMS_SUCCESSFUL)
|
if (sc != RTEMS_SUCCESSFUL)
|
||||||
@@ -127,18 +98,31 @@ fat_buf_release(fat_fs_info_t *fs_info)
|
|||||||
|
|
||||||
if (sec_of_fat && !fs_info->vol.mirror)
|
if (sec_of_fat && !fs_info->vol.mirror)
|
||||||
{
|
{
|
||||||
rtems_bdbuf_buffer *b;
|
uint8_t i;
|
||||||
|
|
||||||
for (i = 1; i < fs_info->vol.fats; i++)
|
for (i = 1; i < fs_info->vol.fats; i++)
|
||||||
{
|
{
|
||||||
sc = rtems_bdbuf_get(fs_info->vol.dd,
|
rtems_bdbuf_buffer *bd;
|
||||||
fs_info->c.blk_num +
|
|
||||||
fs_info->vol.fat_length * i,
|
sec_num = fs_info->c.blk_num + fs_info->vol.fat_length * i,
|
||||||
&b);
|
blk = fat_sector_num_to_block_num(fs_info, sec_num);
|
||||||
|
blk_ofs = fat_sector_offset_to_block_offset(fs_info,
|
||||||
|
sec_num,
|
||||||
|
0);
|
||||||
|
|
||||||
|
if (blk_ofs == 0
|
||||||
|
&& fs_info->vol.bps == fs_info->vol.bytes_per_block)
|
||||||
|
{
|
||||||
|
sc = rtems_bdbuf_get(fs_info->vol.dd, blk, &bd);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sc = rtems_bdbuf_read(fs_info->vol.dd, blk, &bd);
|
||||||
|
}
|
||||||
if ( sc != RTEMS_SUCCESSFUL)
|
if ( sc != RTEMS_SUCCESSFUL)
|
||||||
rtems_set_errno_and_return_minus_one(ENOMEM);
|
rtems_set_errno_and_return_minus_one(ENOMEM);
|
||||||
memcpy(b->buffer, fs_info->sec_buf, fs_info->vol.bps);
|
memcpy(bd->buffer + blk_ofs, fs_info->sec_buf, fs_info->vol.bps);
|
||||||
sc = rtems_bdbuf_release_modified(b);
|
sc = rtems_bdbuf_release_modified(bd);
|
||||||
if ( sc != RTEMS_SUCCESSFUL)
|
if ( sc != RTEMS_SUCCESSFUL)
|
||||||
rtems_set_errno_and_return_minus_one(ENOMEM);
|
rtems_set_errno_and_return_minus_one(ENOMEM);
|
||||||
}
|
}
|
||||||
@@ -182,23 +166,23 @@ _fat_block_read(
|
|||||||
{
|
{
|
||||||
int rc = RC_OK;
|
int rc = RC_OK;
|
||||||
ssize_t cmpltd = 0;
|
ssize_t cmpltd = 0;
|
||||||
uint32_t blk = start;
|
uint32_t sec_num = start;
|
||||||
uint32_t ofs = offset;
|
uint32_t ofs = offset;
|
||||||
rtems_bdbuf_buffer *block = NULL;
|
uint8_t *sec_buf;
|
||||||
uint32_t c = 0;
|
uint32_t c = 0;
|
||||||
|
|
||||||
while (count > 0)
|
while (count > 0)
|
||||||
{
|
{
|
||||||
rc = fat_buf_access(fs_info, blk, FAT_OP_TYPE_READ, &block);
|
rc = fat_buf_access(fs_info, sec_num, FAT_OP_TYPE_READ, &sec_buf);
|
||||||
if (rc != RC_OK)
|
if (rc != RC_OK)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
c = MIN(count, (fs_info->vol.bps - ofs));
|
c = MIN(count, (fs_info->vol.bps - ofs));
|
||||||
memcpy((buff + cmpltd), (block->buffer + ofs), c);
|
memcpy((buff + cmpltd), (sec_buf + ofs), c);
|
||||||
|
|
||||||
count -= c;
|
count -= c;
|
||||||
cmpltd += c;
|
cmpltd += c;
|
||||||
blk++;
|
sec_num++;
|
||||||
ofs = 0;
|
ofs = 0;
|
||||||
}
|
}
|
||||||
return cmpltd;
|
return cmpltd;
|
||||||
@@ -231,29 +215,29 @@ _fat_block_write(
|
|||||||
{
|
{
|
||||||
int rc = RC_OK;
|
int rc = RC_OK;
|
||||||
ssize_t cmpltd = 0;
|
ssize_t cmpltd = 0;
|
||||||
uint32_t blk = start;
|
uint32_t sec_num = start;
|
||||||
uint32_t ofs = offset;
|
uint32_t ofs = offset;
|
||||||
rtems_bdbuf_buffer *block = NULL;
|
uint8_t *sec_buf;
|
||||||
uint32_t c = 0;
|
uint32_t c = 0;
|
||||||
|
|
||||||
while(count > 0)
|
while(count > 0)
|
||||||
{
|
{
|
||||||
c = MIN(count, (fs_info->vol.bps - ofs));
|
c = MIN(count, (fs_info->vol.bps - ofs));
|
||||||
|
|
||||||
if (c == fs_info->vol.bps)
|
if (c == fs_info->vol.bytes_per_block)
|
||||||
rc = fat_buf_access(fs_info, blk, FAT_OP_TYPE_GET, &block);
|
rc = fat_buf_access(fs_info, sec_num, FAT_OP_TYPE_GET, &sec_buf);
|
||||||
else
|
else
|
||||||
rc = fat_buf_access(fs_info, blk, FAT_OP_TYPE_READ, &block);
|
rc = fat_buf_access(fs_info, sec_num, FAT_OP_TYPE_READ, &sec_buf);
|
||||||
if (rc != RC_OK)
|
if (rc != RC_OK)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
memcpy((block->buffer + ofs), (buff + cmpltd), c);
|
memcpy((sec_buf + ofs), (buff + cmpltd), c);
|
||||||
|
|
||||||
fat_buf_mark_modified(fs_info);
|
fat_buf_mark_modified(fs_info);
|
||||||
|
|
||||||
count -= c;
|
count -= c;
|
||||||
cmpltd +=c;
|
cmpltd +=c;
|
||||||
blk++;
|
sec_num++;
|
||||||
ofs = 0;
|
ofs = 0;
|
||||||
}
|
}
|
||||||
return cmpltd;
|
return cmpltd;
|
||||||
@@ -267,9 +251,9 @@ _fat_block_zero(
|
|||||||
uint32_t count)
|
uint32_t count)
|
||||||
{
|
{
|
||||||
int rc = RC_OK;
|
int rc = RC_OK;
|
||||||
uint32_t blk = start;
|
uint32_t sec_num = start;
|
||||||
uint32_t ofs = offset;
|
uint32_t ofs = offset;
|
||||||
rtems_bdbuf_buffer *block = NULL;
|
uint8_t *sec_buf;
|
||||||
uint32_t c = 0;
|
uint32_t c = 0;
|
||||||
|
|
||||||
while(count > 0)
|
while(count > 0)
|
||||||
@@ -277,18 +261,18 @@ _fat_block_zero(
|
|||||||
c = MIN(count, (fs_info->vol.bps - ofs));
|
c = MIN(count, (fs_info->vol.bps - ofs));
|
||||||
|
|
||||||
if (c == fs_info->vol.bps)
|
if (c == fs_info->vol.bps)
|
||||||
rc = fat_buf_access(fs_info, blk, FAT_OP_TYPE_GET, &block);
|
rc = fat_buf_access(fs_info, sec_num, FAT_OP_TYPE_GET, &sec_buf);
|
||||||
else
|
else
|
||||||
rc = fat_buf_access(fs_info, blk, FAT_OP_TYPE_READ, &block);
|
rc = fat_buf_access(fs_info, sec_num, FAT_OP_TYPE_READ, &sec_buf);
|
||||||
if (rc != RC_OK)
|
if (rc != RC_OK)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
memset((block->buffer + ofs), 0, c);
|
memset((block + ofs), 0, c);
|
||||||
|
|
||||||
fat_buf_mark_modified(fs_info);
|
fat_buf_mark_modified(fs_info);
|
||||||
|
|
||||||
count -= c;
|
count -= c;
|
||||||
blk++;
|
sec_num++;
|
||||||
ofs = 0;
|
ofs = 0;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -364,6 +348,11 @@ fat_cluster_write(
|
|||||||
fs_info->vol.spc << fs_info->vol.sec_log2, buff);
|
fs_info->vol.spc << fs_info->vol.sec_log2, buff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool is_cluster_aligned(const fat_vol_t *vol, uint32_t sec_num)
|
||||||
|
{
|
||||||
|
return (sec_num & (vol->spc - 1)) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* fat_init_volume_info --
|
/* fat_init_volume_info --
|
||||||
* Get inforamtion about volume on which filesystem is mounted on
|
* Get inforamtion about volume on which filesystem is mounted on
|
||||||
*
|
*
|
||||||
@@ -444,12 +433,15 @@ fat_init_volume_info(fat_fs_info_t *fs_info, const char *device)
|
|||||||
close(vol->fd);
|
close(vol->fd);
|
||||||
rtems_set_errno_and_return_minus_one( EINVAL );
|
rtems_set_errno_and_return_minus_one( EINVAL );
|
||||||
}
|
}
|
||||||
|
|
||||||
for (vol->sec_mul = 0, i = (vol->bps >> FAT_SECTOR512_BITS); (i & 1) == 0;
|
for (vol->sec_mul = 0, i = (vol->bps >> FAT_SECTOR512_BITS); (i & 1) == 0;
|
||||||
i >>= 1, vol->sec_mul++);
|
i >>= 1, vol->sec_mul++);
|
||||||
for (vol->sec_log2 = 0, i = vol->bps; (i & 1) == 0;
|
for (vol->sec_log2 = 0, i = vol->bps; (i & 1) == 0;
|
||||||
i >>= 1, vol->sec_log2++);
|
i >>= 1, vol->sec_log2++);
|
||||||
|
|
||||||
|
vol->bytes_per_block = vol->bps;
|
||||||
|
vol->bytes_per_block_log2 = vol->sec_log2;
|
||||||
|
vol->sectors_per_block = 1;
|
||||||
|
|
||||||
vol->spc = FAT_GET_BR_SECTORS_PER_CLUSTER(boot_rec);
|
vol->spc = FAT_GET_BR_SECTORS_PER_CLUSTER(boot_rec);
|
||||||
/*
|
/*
|
||||||
* "sectors per cluster" of zero is invalid
|
* "sectors per cluster" of zero is invalid
|
||||||
@@ -638,6 +630,28 @@ fat_init_volume_info(fat_fs_info_t *fs_info, const char *device)
|
|||||||
rtems_set_errno_and_return_minus_one( ENOMEM );
|
rtems_set_errno_and_return_minus_one( ENOMEM );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If possible we will use the cluster size as bdbuf block size for faster
|
||||||
|
* file access. This requires that certain sectors are aligned to cluster
|
||||||
|
* borders.
|
||||||
|
*/
|
||||||
|
if (is_cluster_aligned(vol, vol->data_fsec)
|
||||||
|
&& (FAT_FAT32 == vol->type || is_cluster_aligned(vol, vol->rdir_loc)))
|
||||||
|
{
|
||||||
|
vol->bytes_per_block = vol->bpc;
|
||||||
|
vol->bytes_per_block_log2 = vol->bpc_log2;
|
||||||
|
vol->sectors_per_block = vol->spc;
|
||||||
|
sc = rtems_bdbuf_set_block_size (vol->dd, vol->bytes_per_block, true);
|
||||||
|
if (RTEMS_SUCCESSFUL != sc)
|
||||||
|
{
|
||||||
|
close(vol->fd);
|
||||||
|
free(fs_info->vhash);
|
||||||
|
free(fs_info->rhash);
|
||||||
|
free(fs_info->uino);
|
||||||
|
rtems_set_errno_and_return_minus_one( EIO );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return RC_OK;
|
return RC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -298,6 +298,9 @@ typedef struct fat_vol_s
|
|||||||
uint8_t spc_log2; /* log2 of spc */
|
uint8_t spc_log2; /* log2 of spc */
|
||||||
uint16_t bpc; /* bytes per cluster */
|
uint16_t bpc; /* bytes per cluster */
|
||||||
uint8_t bpc_log2; /* log2 of bytes per cluster */
|
uint8_t bpc_log2; /* log2 of bytes per cluster */
|
||||||
|
uint8_t sectors_per_block; /* sectors per bdbuf block */
|
||||||
|
uint16_t bytes_per_block; /* number of bytes for the bduf block device handling */
|
||||||
|
uint8_t bytes_per_block_log2; /* log2 of bytes_per_block */
|
||||||
uint8_t fats; /* number of FATs */
|
uint8_t fats; /* number of FATs */
|
||||||
uint8_t type; /* FAT type */
|
uint8_t type; /* FAT type */
|
||||||
uint32_t mask;
|
uint32_t mask;
|
||||||
@@ -436,6 +439,25 @@ fat_cluster_num_to_sector512_num(
|
|||||||
fs_info->vol.sec_mul);
|
fs_info->vol.sec_mul);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline uint32_t
|
||||||
|
fat_sector_num_to_block_num (const fat_fs_info_t *fs_info,
|
||||||
|
const uint32_t sector_number)
|
||||||
|
{
|
||||||
|
return sector_number >> (fs_info->vol.bytes_per_block_log2 - fs_info->vol.sec_log2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t
|
||||||
|
fat_sector_offset_to_block_offset (const fat_fs_info_t *fs_info,
|
||||||
|
const uint32_t sector,
|
||||||
|
const uint32_t sector_offset)
|
||||||
|
{
|
||||||
|
return sector_offset +
|
||||||
|
((sector -
|
||||||
|
fat_block_num_to_sector_num (fs_info,
|
||||||
|
fat_sector_num_to_block_num (fs_info, sector)))
|
||||||
|
<< fs_info->vol.sec_log2);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
fat_buf_mark_modified(fat_fs_info_t *fs_info)
|
fat_buf_mark_modified(fat_fs_info_t *fs_info)
|
||||||
{
|
{
|
||||||
@@ -443,8 +465,10 @@ fat_buf_mark_modified(fat_fs_info_t *fs_info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fat_buf_access(fat_fs_info_t *fs_info, uint32_t blk, int op_type,
|
fat_buf_access(fat_fs_info_t *fs_info,
|
||||||
rtems_bdbuf_buffer **buf);
|
uint32_t sec_num,
|
||||||
|
int op_type,
|
||||||
|
uint8_t **sec_buf);
|
||||||
|
|
||||||
int
|
int
|
||||||
fat_buf_release(fat_fs_info_t *fs_info);
|
fat_buf_release(fat_fs_info_t *fs_info);
|
||||||
@@ -469,18 +493,7 @@ _fat_block_zero(fat_fs_info_t *fs_info,
|
|||||||
uint32_t offset,
|
uint32_t offset,
|
||||||
uint32_t count);
|
uint32_t count);
|
||||||
|
|
||||||
int
|
|
||||||
_fat_block_release(fat_fs_info_t *fs_info);
|
|
||||||
|
|
||||||
ssize_t
|
|
||||||
fat_cluster_read(fat_fs_info_t *fs_info,
|
|
||||||
uint32_t cln,
|
|
||||||
void *buff);
|
|
||||||
|
|
||||||
ssize_t
|
|
||||||
fat_cluster_write(fat_fs_info_t *fs_info,
|
|
||||||
uint32_t cln,
|
|
||||||
const void *buff);
|
|
||||||
|
|
||||||
int
|
int
|
||||||
fat_init_volume_info(fat_fs_info_t *fs_info, const char *device);
|
fat_init_volume_info(fat_fs_info_t *fs_info, const char *device);
|
||||||
|
|||||||
@@ -235,7 +235,7 @@ fat_get_fat_cluster(
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
int rc = RC_OK;
|
int rc = RC_OK;
|
||||||
rtems_bdbuf_buffer *block0 = NULL;
|
uint8_t *sec_buf;
|
||||||
uint32_t sec = 0;
|
uint32_t sec = 0;
|
||||||
uint32_t ofs = 0;
|
uint32_t ofs = 0;
|
||||||
|
|
||||||
@@ -247,7 +247,7 @@ fat_get_fat_cluster(
|
|||||||
fs_info->vol.afat_loc;
|
fs_info->vol.afat_loc;
|
||||||
ofs = FAT_FAT_OFFSET(fs_info->vol.type, cln) & (fs_info->vol.bps - 1);
|
ofs = FAT_FAT_OFFSET(fs_info->vol.type, cln) & (fs_info->vol.bps - 1);
|
||||||
|
|
||||||
rc = fat_buf_access(fs_info, sec, FAT_OP_TYPE_READ, &block0);
|
rc = fat_buf_access(fs_info, sec, FAT_OP_TYPE_READ, &sec_buf);
|
||||||
if (rc != RC_OK)
|
if (rc != RC_OK)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
@@ -258,19 +258,19 @@ fat_get_fat_cluster(
|
|||||||
* we are enforced in complex computations for FAT12 to escape CPU
|
* we are enforced in complex computations for FAT12 to escape CPU
|
||||||
* align problems for some architectures
|
* align problems for some architectures
|
||||||
*/
|
*/
|
||||||
*ret_val = (*((uint8_t *)(block0->buffer + ofs)));
|
*ret_val = (*(sec_buf + ofs));
|
||||||
if ( ofs == (fs_info->vol.bps - 1) )
|
if ( ofs == (fs_info->vol.bps - 1) )
|
||||||
{
|
{
|
||||||
rc = fat_buf_access(fs_info, sec + 1, FAT_OP_TYPE_READ,
|
rc = fat_buf_access(fs_info, sec + 1, FAT_OP_TYPE_READ,
|
||||||
&block0);
|
&sec_buf);
|
||||||
if (rc != RC_OK)
|
if (rc != RC_OK)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
*ret_val |= (*((uint8_t *)(block0->buffer)))<<8;
|
*ret_val |= *sec_buf << 8;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*ret_val |= (*((uint8_t *)(block0->buffer + ofs + 1)))<<8;
|
*ret_val |= *(sec_buf + ofs + 1) << 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( FAT_CLUSTER_IS_ODD(cln) )
|
if ( FAT_CLUSTER_IS_ODD(cln) )
|
||||||
@@ -280,12 +280,12 @@ fat_get_fat_cluster(
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case FAT_FAT16:
|
case FAT_FAT16:
|
||||||
*ret_val = *((uint16_t *)(block0->buffer + ofs));
|
*ret_val = *((uint16_t *)(sec_buf + ofs));
|
||||||
*ret_val = CF_LE_W(*ret_val);
|
*ret_val = CF_LE_W(*ret_val);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FAT_FAT32:
|
case FAT_FAT32:
|
||||||
*ret_val = *((uint32_t *)(block0->buffer + ofs));
|
*ret_val = *((uint32_t *)(sec_buf + ofs));
|
||||||
*ret_val = CF_LE_L(*ret_val);
|
*ret_val = CF_LE_L(*ret_val);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -322,7 +322,7 @@ fat_set_fat_cluster(
|
|||||||
uint32_t ofs = 0;
|
uint32_t ofs = 0;
|
||||||
uint16_t fat16_clv = 0;
|
uint16_t fat16_clv = 0;
|
||||||
uint32_t fat32_clv = 0;
|
uint32_t fat32_clv = 0;
|
||||||
rtems_bdbuf_buffer *block0 = NULL;
|
uint8_t *sec_buf = NULL;
|
||||||
|
|
||||||
/* sanity check */
|
/* sanity check */
|
||||||
if ( (cln < 2) || (cln > (fs_info->vol.data_cls + 1)) )
|
if ( (cln < 2) || (cln > (fs_info->vol.data_cls + 1)) )
|
||||||
@@ -332,7 +332,7 @@ fat_set_fat_cluster(
|
|||||||
fs_info->vol.afat_loc;
|
fs_info->vol.afat_loc;
|
||||||
ofs = FAT_FAT_OFFSET(fs_info->vol.type, cln) & (fs_info->vol.bps - 1);
|
ofs = FAT_FAT_OFFSET(fs_info->vol.type, cln) & (fs_info->vol.bps - 1);
|
||||||
|
|
||||||
rc = fat_buf_access(fs_info, sec, FAT_OP_TYPE_READ, &block0);
|
rc = fat_buf_access(fs_info, sec, FAT_OP_TYPE_READ, &sec_buf);
|
||||||
if (rc != RC_OK)
|
if (rc != RC_OK)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
@@ -342,80 +342,65 @@ fat_set_fat_cluster(
|
|||||||
if ( FAT_CLUSTER_IS_ODD(cln) )
|
if ( FAT_CLUSTER_IS_ODD(cln) )
|
||||||
{
|
{
|
||||||
fat16_clv = ((uint16_t )in_val) << FAT_FAT12_SHIFT;
|
fat16_clv = ((uint16_t )in_val) << FAT_FAT12_SHIFT;
|
||||||
*((uint8_t *)(block0->buffer + ofs)) =
|
*(sec_buf + ofs) &= 0x0F;
|
||||||
(*((uint8_t *)(block0->buffer + ofs))) & 0x0F;
|
|
||||||
|
|
||||||
*((uint8_t *)(block0->buffer + ofs)) =
|
*(sec_buf + ofs) |= (uint8_t)(fat16_clv & 0x00F0);
|
||||||
(*((uint8_t *)(block0->buffer + ofs))) |
|
|
||||||
(uint8_t )(fat16_clv & 0x00FF);
|
|
||||||
|
|
||||||
fat_buf_mark_modified(fs_info);
|
fat_buf_mark_modified(fs_info);
|
||||||
|
|
||||||
if ( ofs == (fs_info->vol.bps - 1) )
|
if ( ofs == (fs_info->vol.bps - 1) )
|
||||||
{
|
{
|
||||||
rc = fat_buf_access(fs_info, sec + 1, FAT_OP_TYPE_READ,
|
rc = fat_buf_access(fs_info, sec + 1, FAT_OP_TYPE_READ,
|
||||||
&block0);
|
&sec_buf);
|
||||||
if (rc != RC_OK)
|
if (rc != RC_OK)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
*((uint8_t *)(block0->buffer)) &= 0x00;
|
*sec_buf &= 0x00;
|
||||||
|
|
||||||
*((uint8_t *)(block0->buffer)) =
|
*sec_buf |= (uint8_t)((fat16_clv & 0xFF00)>>8);
|
||||||
(*((uint8_t *)(block0->buffer))) |
|
|
||||||
(uint8_t )((fat16_clv & 0xFF00)>>8);
|
|
||||||
|
|
||||||
fat_buf_mark_modified(fs_info);
|
fat_buf_mark_modified(fs_info);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*((uint8_t *)(block0->buffer + ofs + 1)) &= 0x00;
|
*(sec_buf + ofs + 1) &= 0x00;
|
||||||
|
|
||||||
*((uint8_t *)(block0->buffer + ofs + 1)) =
|
*(sec_buf + ofs + 1) |= (uint8_t )((fat16_clv & 0xFF00)>>8);
|
||||||
(*((uint8_t *)(block0->buffer + ofs + 1))) |
|
|
||||||
(uint8_t )((fat16_clv & 0xFF00)>>8);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fat16_clv = ((uint16_t )in_val) & FAT_FAT12_MASK;
|
fat16_clv = ((uint16_t )in_val) & FAT_FAT12_MASK;
|
||||||
*((uint8_t *)(block0->buffer + ofs)) &= 0x00;
|
*(sec_buf + ofs) &= 0x00;
|
||||||
|
|
||||||
*((uint8_t *)(block0->buffer + ofs)) =
|
*(sec_buf + ofs) |= (uint8_t)(fat16_clv & 0x00FF);
|
||||||
(*((uint8_t *)(block0->buffer + ofs))) |
|
|
||||||
(uint8_t )(fat16_clv & 0x00FF);
|
|
||||||
|
|
||||||
fat_buf_mark_modified(fs_info);
|
fat_buf_mark_modified(fs_info);
|
||||||
|
|
||||||
if ( ofs == (fs_info->vol.bps - 1) )
|
if ( ofs == (fs_info->vol.bps - 1) )
|
||||||
{
|
{
|
||||||
rc = fat_buf_access(fs_info, sec + 1, FAT_OP_TYPE_READ,
|
rc = fat_buf_access(fs_info, sec + 1, FAT_OP_TYPE_READ,
|
||||||
&block0);
|
&sec_buf);
|
||||||
if (rc != RC_OK)
|
if (rc != RC_OK)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
*((uint8_t *)(block0->buffer)) =
|
*sec_buf &= 0xF0;
|
||||||
(*((uint8_t *)(block0->buffer))) & 0xF0;
|
|
||||||
|
|
||||||
*((uint8_t *)(block0->buffer)) =
|
*sec_buf |= (uint8_t)((fat16_clv & 0xFF00)>>8);
|
||||||
(*((uint8_t *)(block0->buffer))) |
|
|
||||||
(uint8_t )((fat16_clv & 0xFF00)>>8);
|
|
||||||
|
|
||||||
fat_buf_mark_modified(fs_info);
|
fat_buf_mark_modified(fs_info);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*((uint8_t *)(block0->buffer + ofs + 1)) =
|
*(sec_buf + ofs + 1) &= 0xF0;
|
||||||
(*((uint8_t *)(block0->buffer + ofs + 1))) & 0xF0;
|
|
||||||
|
|
||||||
*((uint8_t *)(block0->buffer + ofs+1)) =
|
*(sec_buf + ofs+1) |= (uint8_t)((fat16_clv & 0xFF00)>>8);
|
||||||
(*((uint8_t *)(block0->buffer + ofs+1))) |
|
|
||||||
(uint8_t )((fat16_clv & 0xFF00)>>8);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FAT_FAT16:
|
case FAT_FAT16:
|
||||||
*((uint16_t *)(block0->buffer + ofs)) =
|
*((uint16_t *)(sec_buf + ofs)) =
|
||||||
(uint16_t )(CT_LE_W(in_val));
|
(uint16_t )(CT_LE_W(in_val));
|
||||||
fat_buf_mark_modified(fs_info);
|
fat_buf_mark_modified(fs_info);
|
||||||
break;
|
break;
|
||||||
@@ -423,11 +408,9 @@ fat_set_fat_cluster(
|
|||||||
case FAT_FAT32:
|
case FAT_FAT32:
|
||||||
fat32_clv = CT_LE_L((in_val & FAT_FAT32_MASK));
|
fat32_clv = CT_LE_L((in_val & FAT_FAT32_MASK));
|
||||||
|
|
||||||
*((uint32_t *)(block0->buffer + ofs)) =
|
*((uint32_t *)(sec_buf + ofs)) &= CT_LE_L(0xF0000000);
|
||||||
(*((uint32_t *)(block0->buffer + ofs))) & (CT_LE_L(0xF0000000));
|
|
||||||
|
|
||||||
*((uint32_t *)(block0->buffer + ofs)) =
|
*((uint32_t *)(sec_buf + ofs)) |= fat32_clv;
|
||||||
fat32_clv | (*((uint32_t *)(block0->buffer + ofs)));
|
|
||||||
|
|
||||||
fat_buf_mark_modified(fs_info);
|
fat_buf_mark_modified(fs_info);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -191,6 +191,7 @@ msdos_file_stat(
|
|||||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||||
msdos_fs_info_t *fs_info = loc->mt_entry->fs_info;
|
msdos_fs_info_t *fs_info = loc->mt_entry->fs_info;
|
||||||
fat_file_fd_t *fat_fd = loc->node_access;
|
fat_file_fd_t *fat_fd = loc->node_access;
|
||||||
|
uint32_t cl_mask = fs_info->fat.vol.bpc - 1;
|
||||||
|
|
||||||
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
|
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
|
||||||
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
|
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
|
||||||
@@ -202,8 +203,9 @@ msdos_file_stat(
|
|||||||
buf->st_mode = S_IFREG | S_IRWXU | S_IRWXG | S_IRWXO;
|
buf->st_mode = S_IFREG | S_IRWXU | S_IRWXG | S_IRWXO;
|
||||||
buf->st_rdev = 0ll;
|
buf->st_rdev = 0ll;
|
||||||
buf->st_size = fat_fd->fat_file_size;
|
buf->st_size = fat_fd->fat_file_size;
|
||||||
buf->st_blocks = fat_fd->fat_file_size >> FAT_SECTOR512_BITS;
|
buf->st_blocks = ((fat_fd->fat_file_size + cl_mask) & ~cl_mask)
|
||||||
buf->st_blksize = fs_info->fat.vol.bps;
|
>> FAT_SECTOR512_BITS;
|
||||||
|
buf->st_blksize = fs_info->fat.vol.bpc;
|
||||||
buf->st_mtime = fat_fd->mtime;
|
buf->st_mtime = fat_fd->mtime;
|
||||||
|
|
||||||
rtems_semaphore_release(fs_info->vol_sema);
|
rtems_semaphore_release(fs_info->vol_sema);
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
msdos_format_request_param_t rqdata = {
|
msdos_format_request_param_t rqdata = {
|
||||||
OEMName: "RTEMS",
|
OEMName: "RTEMS",
|
||||||
VolLabel: "RTEMSDisk",
|
VolLabel: "RTEMSDisk",
|
||||||
sectors_per_cluster: 0,
|
sectors_per_cluster: 2,
|
||||||
fat_num: 0,
|
fat_num: 0,
|
||||||
files_per_root_dir: 0,
|
files_per_root_dir: 0,
|
||||||
media: 0,
|
media: 0,
|
||||||
|
|||||||
Reference in New Issue
Block a user