Skip to content
Open
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
60 changes: 46 additions & 14 deletions kernel/fatfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1024,17 +1024,6 @@ COUNT map_cluster(REG f_node_ptr fnp, COUNT mode)
cluster = extend(fnp);
if (cluster == LONG_LAST_CLUSTER)
return DE_HNDLDSKFULL;

/* ecm: finally the right solution, only extend/modify
file size after having just appended a cluster. */
fnp->f_dir.dir_size =
(((ULONG)fnp->f_cluster_offset + 2)
/* at 0 we will increment to 1, having allocated the second
cluster, so + 2 for the then-total size. */
* (ULONG)fnp->f_dpb->dpb_secsize)
<<
fnp->f_dpb->dpb_shftcnt;
merge_file_changes(fnp, FALSE);
}

fnp->f_cluster = cluster;
Expand All @@ -1055,7 +1044,7 @@ COUNT map_cluster(REG f_node_ptr fnp, COUNT mode)
/* #define WRITEZEROS 1 */
/* but because we want to be compatible, we don't do this by */
/* default */
STATIC COUNT dos_extend(f_node_ptr fnp)
STATIC COUNT dos_extend(f_node_ptr fnp, BOOL emptywrite)
{
#ifdef WRITEZEROS
struct buffer FAR *bp;
Expand All @@ -1075,8 +1064,39 @@ STATIC COUNT dos_extend(f_node_ptr fnp)
while (count > 0)
#endif
{
if (map_cluster(fnp, XFR_WRITE) != SUCCESS)
BOOL special = 0;
if (emptywrite
#ifdef WRITEZEROS
&& fnp->f_offset != 0
#else
/* f_offset != 0 always true here */
#endif
&& ((fnp->f_offset &
(((ULONG)fnp->f_dpb->dpb_secsize
<< fnp->f_dpb->dpb_shftcnt) - 1)
)
== 0)
) {
special = 1;
-- fnp->f_offset;
}
if (map_cluster(fnp, XFR_WRITE) != SUCCESS) {
if (special) ++ fnp->f_offset;
if (fnp->f_cluster != FREE) {
/* ecm: write size if couldn't satisfy full request,
but at least one cluster is allocated. */
fnp->f_dir.dir_size =
(((ULONG)fnp->f_cluster_offset + 1)
/* at 0 we have incremented to 1, having allocated the second
cluster, so + 1 for the then-total size. */
* (ULONG)fnp->f_dpb->dpb_secsize)
<<
fnp->f_dpb->dpb_shftcnt;
merge_file_changes(fnp, FALSE);
}
return DE_HNDLDSKFULL;
}
if (special) ++ fnp->f_offset;

#ifdef WRITEZEROS
/* Compute the block within the cluster and the offset */
Expand Down Expand Up @@ -1106,6 +1126,18 @@ STATIC COUNT dos_extend(f_node_ptr fnp)
}
if (bp == NULL)
{
if (fnp->f_cluster != FREE) {
/* ecm: write size if couldn't satisfy full request,
but at least one cluster is allocated. */
fnp->f_dir.dir_size =
(((ULONG)fnp->f_cluster_offset + 1)
/* at 0 we have incremented to 1, having allocated the second
cluster, so + 1 for the then-total size. */
* (ULONG)fnp->f_dpb->dpb_secsize)
<<
fnp->f_dpb->dpb_shftcnt;
merge_file_changes(fnp, FALSE);
}
return DE_ACCESS;
}

Expand Down Expand Up @@ -1221,7 +1253,7 @@ long rwblock(COUNT fd, VOID FAR * buffer, UCOUNT count, int mode)
/* mark file as modified and set date not valid any more */
fnp->f_flags &= ~(SFT_FCLEAN|SFT_FDATE);

if (dos_extend(fnp) != SUCCESS)
if (dos_extend(fnp, count == 0) != SUCCESS)
{
/* ecm: control flow may end up here if CX = 0000h and
the extending failed to allocate a cluster
Expand Down