Imported Upstream version 4.0.35
[platform/upstream/mtools.git] / file.c
diff --git a/file.c b/file.c
index f7a631c..d72c7d0 100644 (file)
--- a/file.c
+++ b/file.c
@@ -158,7 +158,7 @@ static unsigned int _countBlocks(Fs_t *This, unsigned int block)
        unsigned int rel, oldabs, oldrel;
 
        blocks = 0;
-       
+
        oldabs = oldrel = rel = 0;
 
        while (block <= This->last_fat && block != 1 && block) {
@@ -300,7 +300,7 @@ static int normal_map(File_t *This, uint32_t where, uint32_t *len, int mode,
        }
 
        RelCluNr = where / clus_size;
-       
+
        if (RelCluNr >= This->PreviousRelCluNr){
                CurCluNr = This->PreviousRelCluNr;
                AbsCluNr = This->PreviousAbsCluNr;
@@ -324,7 +324,7 @@ static int normal_map(File_t *This, uint32_t where, uint32_t *len, int mode,
                                AbsCluNr, NewCluNr);
                        exit(1);
                }
-               if(CurCluNr == RelCluNr + NrClu)                        
+               if(CurCluNr == RelCluNr + NrClu)
                        break;
                if (NewCluNr > Fs->last_fat && mode == MT_WRITE){
                        /* if at end, and writing, extend it */
@@ -352,11 +352,14 @@ static int normal_map(File_t *This, uint32_t where, uint32_t *len, int mode,
        }
 
        maximize(*len, (1 + CurCluNr - RelCluNr) * clus_size - offset);
-       
+
        end = where + *len;
        if(batchmode &&
           mode == MT_WRITE &&
           end >= This->FileSize) {
+               /* In batch mode, when writing at end of file, "pad"
+                * to nearest cluster boundary so that we don't have
+                * to read that data back from disk. */
                *len += ROUND_UP(end, clus_size) - end;
        }
 
@@ -366,9 +369,9 @@ static int normal_map(File_t *This, uint32_t where, uint32_t *len, int mode,
                exit(1);
        }
 
-       *res = sectorsToBytes((Stream_t*)Fs,
+       *res = sectorsToBytes(Fs,
                              (This->PreviousAbsCluNr-2) * Fs->cluster_size +
-                             Fs->clus_start) + offset;
+                             Fs->clus_start) + to_mt_off_t(offset);
        return 1;
 }
 
@@ -378,7 +381,7 @@ static int root_map(File_t *This, uint32_t where, uint32_t *len,
 {
        Fs_t *Fs = This->Fs;
 
-       if(Fs->dir_len * Fs->sector_size + 0u < (size_t) where) {
+       if(Fs->dir_len * Fs->sector_size < where) {
                *len = 0;
                errno = ENOSPC;
                return -2;
@@ -387,11 +390,12 @@ static int root_map(File_t *This, uint32_t where, uint32_t *len,
        maximize(*len, Fs->dir_len * Fs->sector_size - where);
         if (*len == 0)
             return 0;
-       
-       *res = sectorsToBytes((Stream_t*)Fs, Fs->dir_start) + where;
+
+       *res = sectorsToBytes(Fs, Fs->dir_start) +
+               to_mt_off_t(where);
        return 1;
 }
-       
+
 
 static ssize_t read_file(Stream_t *Stream, char *buf, mt_off_t iwhere,
                         size_t ilen)
@@ -401,9 +405,9 @@ static ssize_t read_file(Stream_t *Stream, char *buf, mt_off_t iwhere,
        int err;
        uint32_t where = truncMtOffTo32u(iwhere);
        uint32_t len = truncSizeTo32u(ilen);
-       
+
        Stream_t *Disk = This->Fs->Next;
-       
+
        err = This->map(This, where, &len, MT_READ, &pos);
        if(err <= 0)
                return err;
@@ -420,13 +424,14 @@ static ssize_t write_file(Stream_t *Stream, char *buf,
        uint32_t bytesWritten;
        Stream_t *Disk = This->Fs->Next;
        uint32_t where = truncMtOffTo32u(iwhere);
+       uint32_t maxLen = UINT32_MAX-where;
        uint32_t len;
        int err;
 
-       if(iwhere+(mt_off_t)ilen > UINT32_MAX) {
-               ilen=(size_t) (UINT32_MAX-iwhere);
-       }
-       len = truncSizeTo32u(ilen);
+       if(ilen > maxLen) {
+               len = maxLen;
+       } else
+               len = (uint32_t) ilen;
        requestedLen = len;
        err = This->map(This, where, &len, MT_WRITE, &pos);
        if( err <= 0)
@@ -439,13 +444,17 @@ static ssize_t write_file(Stream_t *Stream, char *buf,
                /* Error occured */
                return ret;
        if((uint32_t)ret > requestedLen)
+               /* More data than requested may be written to lower
+                * levels if batch mode is active, in order to "pad"
+                * the last cluster of a file, so that we don't have
+                * to read that back from disk */
                bytesWritten = requestedLen;
        else
-               bytesWritten = requestedLen;
+               bytesWritten = (uint32_t)ret;
        if (where + bytesWritten > This->FileSize )
                This->FileSize = where + bytesWritten;
        recalcPreallocSize(This);
-       return ret;
+       return (ssize_t)bytesWritten;
 }
 
 
@@ -481,7 +490,7 @@ static __inline__ time_t conv_stamp(struct directory *dir)
        {
                struct timeval tv;
                struct timezone tz;
-               
+
                gettimeofday(&tv, &tz);
                tzone = tz.tz_minuteswest * 60L;
        }
@@ -513,7 +522,7 @@ static __inline__ time_t conv_stamp(struct directory *dir)
 }
 
 
-static int get_file_data(Stream_t *Stream, time_t *date, mt_size_t *size,
+static int get_file_data(Stream_t *Stream, time_t *date, mt_off_t *size,
                         int *type, uint32_t *address)
 {
        DeclareThis(File_t);
@@ -521,7 +530,7 @@ static int get_file_data(Stream_t *Stream, time_t *date, mt_size_t *size,
        if(date)
                *date = conv_stamp(& This->direntry.dir);
        if(size)
-               *size = (mt_size_t) This->FileSize;
+               *size = to_mt_off_t(This->FileSize);
        if(type)
                *type = This->direntry.dir.attr & ATTR_DIR;
        if(address)
@@ -621,7 +630,7 @@ static int comp(void *Stream, void *Stream2)
 static void init_hash(void)
 {
        static int is_initialised=0;
-       
+
        if(!is_initialised){
                make_ht(func1, func2, comp, 20, &filehash);
                is_initialised = 1;