Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions components/dfs/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@ if RT_USING_DFS
bool "Using working directory"
default y

config RT_USING_DFS_LARGE_FILE
bool "Enable large file support with 64-bit file offsets"
default n
select RT_KLIBC_USING_VSNPRINTF_LONGLONG if !RT_KLIBC_USING_LIBC_VSNPRINTF
help
Enable 64-bit signed off_t for DFS/POSIX file offsets and
file sizes. This is required to access FAT32 files larger
than 2GB on 32-bit platforms. Enabling this option changes
the ABI of file offset related APIs and structures.

if RT_USING_DFS_V1
config RT_USING_DFS_MNTTABLE
bool "Using mount table for file system"
Expand Down
2 changes: 1 addition & 1 deletion components/dfs/dfs_v1/filesystems/cromfs/dfs_cromfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -788,7 +788,7 @@ static int dfs_cromfs_read(struct dfs_file *file, void *buf, size_t count)
return length;
}

static int dfs_cromfs_lseek(struct dfs_file *file, off_t offset)
static off_t dfs_cromfs_lseek(struct dfs_file *file, off_t offset)
{
if (offset <= file->vnode->size)
{
Expand Down
26 changes: 24 additions & 2 deletions components/dfs/dfs_v1/filesystems/elmfat/dfs_elm.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,18 @@ static int elm_result_to_dfs(FRESULT result)
return status;
}

static int dfs_elm_off_to_fsize(off_t offset, FSIZE_t *fsize)
{
if (offset < 0)
return -EINVAL;

if ((uint64_t)offset > (uint64_t)(FSIZE_t)-1)
return -EFBIG;

*fsize = (FSIZE_t)offset;
return 0;
}

/* results:
* -1, no space to install fatfs driver
* >= 0, there is an space to install fatfs driver
Expand Down Expand Up @@ -505,12 +517,16 @@ int dfs_elm_ioctl(struct dfs_file *file, int cmd, void *args)
FIL *fd;
FSIZE_t fptr, length;
FRESULT result = FR_OK;
int ret;
fd = (FIL *)(file->data);
RT_ASSERT(fd != RT_NULL);

/* save file read/write point */
fptr = fd->fptr;
length = *(off_t*)args;
ret = dfs_elm_off_to_fsize(*(off_t *)args, &length);
if (ret < 0)
return ret;

if (length <= fd->obj.objsize)
{
fd->fptr = length;
Expand Down Expand Up @@ -597,12 +613,18 @@ off_t dfs_elm_lseek(struct dfs_file *file, off_t offset)
if (file->vnode->type == FT_REGULAR)
{
FIL *fd;
FSIZE_t fsize;
int ret;

/* regular file type */
fd = (FIL *)(file->data);
RT_ASSERT(fd != RT_NULL);

result = f_lseek(fd, offset);
ret = dfs_elm_off_to_fsize(offset, &fsize);
if (ret < 0)
return ret;

result = f_lseek(fd, fsize);
if (result == FR_OK)
{
/* return current position */
Expand Down
2 changes: 1 addition & 1 deletion components/dfs/dfs_v1/filesystems/nfs/dfs_nfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -685,7 +685,7 @@ int nfs_write(struct dfs_file *file, const void *buf, size_t count)
return total;
}

int nfs_lseek(struct dfs_file *file, off_t offset)
off_t nfs_lseek(struct dfs_file *file, off_t offset)
{
nfs_file *fd;
nfs_filesystem *nfs;
Expand Down
2 changes: 1 addition & 1 deletion components/dfs/dfs_v1/filesystems/skeleton/skeleton.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ int dfs_skt_read(struct dfs_file *file, void *buf, rt_size_t count)
return count;
}

int dfs_skt_lseek(struct dfs_file *file, rt_off_t offset)
off_t dfs_skt_lseek(struct dfs_file *file, off_t offset)
{
return -RT_EIO;
}
Expand Down
4 changes: 4 additions & 0 deletions components/dfs/dfs_v1/include/dfs_file.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,11 @@ struct dfs_vnode
const struct dfs_file_ops *fops;
uint32_t flags; /* self flags, is dir etc.. */

#ifdef RT_USING_DFS_LARGE_FILE
off_t size; /* Size in bytes */
#else
size_t size; /* Size in bytes */
#endif
void *data; /* Specific file system data */
};

Expand Down
48 changes: 47 additions & 1 deletion components/dfs/dfs_v1/src/dfs_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -580,7 +580,7 @@ int dfs_file_flush(struct dfs_file *fd)
*/
off_t dfs_file_lseek(struct dfs_file *fd, off_t offset)
{
int result;
off_t result;

if (fd == NULL)
return -EINVAL;
Expand Down Expand Up @@ -783,6 +783,48 @@ int dfs_file_mmap2(struct dfs_file *fd, struct dfs_mmap2_args *mmap2)
#ifdef RT_USING_FINSH
#include <finsh.h>

#ifdef RT_USING_DFS_LARGE_FILE
static void dfs_print_file_size(off_t size)
{
char tmp[21];
char buf[22];
int index = 0;
int out = 0;
uint64_t value;

if (size < 0)
{
value = (uint64_t)(-(size + 1)) + 1;
buf[out++] = '-';
}
else
{
value = (uint64_t)size;
}

if (value == 0)
{
tmp[index++] = '0';
}
else
{
while ((value != 0) && (index < (int)sizeof(tmp)))
{
tmp[index++] = (char)('0' + (value % 10));
value /= 10;
}
}

while ((index > 0) && (out + 1 < (int)sizeof(buf)))
{
buf[out++] = tmp[--index];
}
buf[out] = '\0';

rt_kprintf(" %-25s\n", buf);
}
#endif

void ls(const char *pathname)
{
struct dfs_file fd;
Expand Down Expand Up @@ -835,7 +877,11 @@ void ls(const char *pathname)
}
else
{
#ifdef RT_USING_DFS_LARGE_FILE
dfs_print_file_size(stat.st_size);
#else
rt_kprintf(" %-25lu\n", (unsigned long)stat.st_size);
#endif
}
}
else
Expand Down
2 changes: 1 addition & 1 deletion components/dfs/dfs_v1/src/dfs_posix.c
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ RTM_EXPORT(write);
*/
off_t lseek(int fd, off_t offset, int whence)
{
int result;
off_t result;
struct dfs_file *d;

d = fd_get(fd);
Expand Down
84 changes: 67 additions & 17 deletions components/dfs/dfs_v2/filesystems/elmfat/dfs_elm.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,18 @@ static int elm_result_to_dfs(FRESULT result)
return status;
}

static int dfs_elm_off_to_fsize(off_t offset, FSIZE_t *fsize)
{
if (offset < 0)
return -EINVAL;

if ((uint64_t)offset > (uint64_t)(FSIZE_t)-1)
return -EFBIG;

*fsize = (FSIZE_t)offset;
return 0;
}

/* results:
* -1, no space to install fatfs driver
* >= 0, there is an space to install fatfs driver
Expand Down Expand Up @@ -549,7 +561,7 @@ int dfs_elm_ioctl(struct dfs_file *file, int cmd, void *args)
{
case RT_FIOFTRUNCATE:
{
off_t offset = (off_t)(size_t)(args);
off_t offset = *(off_t *)args;
return dfs_elm_truncate(file, offset);
}
case F_GETLK:
Expand All @@ -565,6 +577,8 @@ ssize_t dfs_elm_read(struct dfs_file *file, void *buf, size_t len, off_t *pos)
FIL *fd;
FRESULT result = FR_OK;
UINT byte_read;
FSIZE_t fsize;
int ret;

if (file->vnode->type == FT_DIRECTORY)
{
Expand All @@ -573,13 +587,20 @@ ssize_t dfs_elm_read(struct dfs_file *file, void *buf, size_t len, off_t *pos)

if (file->vnode->size > *pos)
{
ret = dfs_elm_off_to_fsize(*pos, &fsize);
if (ret < 0)
return ret;

fd = (FIL *)(file->vnode->data);
RT_ASSERT(fd != RT_NULL);
rt_mutex_take(&file->vnode->lock, RT_WAITING_FOREVER);
f_lseek(fd, *pos);
result = f_read(fd, buf, len, &byte_read);
/* update position */
*pos = fd->fptr;
result = f_lseek(fd, fsize);
if (result == FR_OK)
{
result = f_read(fd, buf, len, &byte_read);
/* update position */
*pos = fd->fptr;
}
rt_mutex_release(&file->vnode->lock);
if (result == FR_OK)
return byte_read;
Expand All @@ -593,6 +614,8 @@ ssize_t dfs_elm_write(struct dfs_file *file, const void *buf, size_t len, off_t
FIL *fd;
FRESULT result;
UINT byte_write;
FSIZE_t fsize;
int ret;

if (file->vnode->type == FT_DIRECTORY)
{
Expand All @@ -601,12 +624,19 @@ ssize_t dfs_elm_write(struct dfs_file *file, const void *buf, size_t len, off_t

fd = (FIL *)(file->vnode->data);
RT_ASSERT(fd != RT_NULL);
ret = dfs_elm_off_to_fsize(*pos, &fsize);
if (ret < 0)
return ret;

rt_mutex_take(&file->vnode->lock, RT_WAITING_FOREVER);
f_lseek(fd, *pos);
result = f_write(fd, buf, len, &byte_write);
/* update position and file size */
*pos = fd->fptr;
file->vnode->size = f_size(fd);
result = f_lseek(fd, fsize);
if (result == FR_OK)
{
result = f_write(fd, buf, len, &byte_write);
/* update position and file size */
*pos = fd->fptr;
file->vnode->size = f_size(fd);
}
rt_mutex_release(&file->vnode->lock);
if (result == FR_OK)
return byte_write;
Expand Down Expand Up @@ -650,12 +680,18 @@ off_t dfs_elm_lseek(struct dfs_file *file, off_t offset, int wherece)
if (file->vnode->type == FT_REGULAR)
{
FIL *fd;
FSIZE_t fsize;
int ret;

/* regular file type */
fd = (FIL *)(file->vnode->data);
RT_ASSERT(fd != RT_NULL);
ret = dfs_elm_off_to_fsize(offset, &fsize);
if (ret < 0)
return ret;

rt_mutex_take(&file->vnode->lock, RT_WAITING_FOREVER);
result = f_lseek(fd, offset);
result = f_lseek(fd, fsize);
pos = fd->fptr;
rt_mutex_release(&file->vnode->lock);
if (result == FR_OK)
Expand Down Expand Up @@ -687,21 +723,26 @@ off_t dfs_elm_lseek(struct dfs_file *file, off_t offset, int wherece)
static int dfs_elm_truncate(struct dfs_file *file, off_t offset)
{
FIL *fd;
FSIZE_t fptr;
FSIZE_t fptr, fsize;
FRESULT result = FR_OK;
int ret;
fd = (FIL *)(file->vnode->data);
RT_ASSERT(fd != RT_NULL);

ret = dfs_elm_off_to_fsize(offset, &fsize);
if (ret < 0)
return ret;

/* save file read/write point */
fptr = fd->fptr;
if (offset <= fd->obj.objsize)
if (fsize <= fd->obj.objsize)
{
fd->fptr = offset;
fd->fptr = fsize;
result = f_truncate(fd);
}
else
{
result = f_lseek(fd, offset);
result = f_lseek(fd, fsize);
}
/* restore file read/write point */
fd->fptr = fptr;
Expand Down Expand Up @@ -1042,6 +1083,8 @@ ssize_t dfs_elm_page_write(struct dfs_page *page)
FIL *fd;
FRESULT result;
UINT byte_write;
FSIZE_t fsize;
int ret;

if (page->aspace->vnode->type == FT_DIRECTORY)
{
Expand All @@ -1050,9 +1093,16 @@ ssize_t dfs_elm_page_write(struct dfs_page *page)

fd = (FIL *)(page->aspace->vnode->data);
RT_ASSERT(fd != RT_NULL);
ret = dfs_elm_off_to_fsize(page->fpos, &fsize);
if (ret < 0)
return ret;

rt_mutex_take(&page->aspace->vnode->lock, RT_WAITING_FOREVER);
f_lseek(fd, page->fpos);
result = f_write(fd, page->page, page->len, &byte_write);
result = f_lseek(fd, fsize);
if (result == FR_OK)
{
result = f_write(fd, page->page, page->len, &byte_write);
}
rt_mutex_release(&page->aspace->vnode->lock);
if (result == FR_OK)
{
Expand Down
2 changes: 1 addition & 1 deletion components/dfs/dfs_v2/filesystems/ramfs/dfs_ramfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ int dfs_ramfs_write(struct dfs_file *fd, const void *buf, size_t count)
return count;
}

int dfs_ramfs_lseek(struct dfs_file *file, off_t offset)
off_t dfs_ramfs_lseek(struct dfs_file *file, off_t offset)
{
if (offset <= (off_t)file->vnode->size)
{
Expand Down
2 changes: 1 addition & 1 deletion components/dfs/dfs_v2/filesystems/skeleton/skeleton.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ int dfs_skt_read(struct dfs_file *file, void *buf, rt_size_t count)
return count;
}

int dfs_skt_lseek(struct dfs_file *file, rt_off_t offset)
off_t dfs_skt_lseek(struct dfs_file *file, off_t offset)
{
return -RT_EIO;
}
Expand Down
4 changes: 4 additions & 0 deletions components/dfs/dfs_v2/include/dfs_file.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,11 @@ struct dfs_vnode

struct dfs_mnt *mnt; /* which mounted file system does this vnode belong to */

#ifdef RT_USING_DFS_LARGE_FILE
off_t size;
#else
size_t size;
#endif
uint32_t nlink;

const struct dfs_file_ops *fops;
Expand Down
Loading
Loading