diff --git a/rosapps/applications/sysutils/dosfsck/dosfsck.c b/rosapps/applications/sysutils/dosfsck/dosfsck.c index 15daf1bc686..7c015421dfc 100644 --- a/rosapps/applications/sysutils/dosfsck/dosfsck.c +++ b/rosapps/applications/sysutils/dosfsck/dosfsck.c @@ -24,7 +24,7 @@ #include "check.h" -int interactive = 0,list = 0,test = 0,verbose = 0,write_immed = 0; +int interactive = 0,list = 0,test = 0,verbose = 0,write_immed = 0,no_change_list=0; int atari_format = 0; unsigned n_files = 0; void *mem_queue = NULL; diff --git a/rosapps/applications/sysutils/dosfsck/dosfsck.h b/rosapps/applications/sysutils/dosfsck/dosfsck.h index 3789b8fdf7f..0f44735f4a2 100644 --- a/rosapps/applications/sysutils/dosfsck/dosfsck.h +++ b/rosapps/applications/sysutils/dosfsck/dosfsck.h @@ -162,7 +162,7 @@ typedef struct { #define offsetof(t,e) ((int)&(((t *)0)->e)) #endif -extern int interactive,list,verbose,test,write_immed; +extern int interactive,list,verbose,test,write_immed,no_change_list; extern int atari_format; extern unsigned n_files; extern void *mem_queue; diff --git a/rosapps/applications/sysutils/dosfsck/io.c b/rosapps/applications/sysutils/dosfsck/io.c index 06ed8792129..43ee3048270 100644 --- a/rosapps/applications/sysutils/dosfsck/io.c +++ b/rosapps/applications/sysutils/dosfsck/io.c @@ -107,13 +107,8 @@ void fs_read(loff_t pos,int size,void *data) const size_t seek_delta = (size_t)(pos - seekpos_aligned); // TMN: const size_t readsize = (size_t)(pos - seekpos_aligned) + readsize_aligned; // TMN: char* tmpBuf = malloc(readsize_aligned); // TMN: -#ifdef _MSC_VER if (llseek(fd,seekpos_aligned,0) != seekpos_aligned) pdie("Seek to %I64d",pos); - if ((got = read(fd,tmpBuf,readsize_aligned)) < 0) pdie("Read %d bytes at %I64dd",size,pos); -#else - if (llseek(fd,seekpos_aligned,0) != seekpos_aligned) pdie("Seek to %lld",pos); - if ((got = read(fd,tmpBuf,readsize_aligned)) < 0) pdie("Read %d bytes at %lld",size,pos); -#endif + if ((got = read(fd,tmpBuf,readsize_aligned)) < 0) pdie("Read %d bytes at %I64d",size,pos); assert(got >= size); got = size; assert(seek_delta + size <= readsize); @@ -123,7 +118,7 @@ void fs_read(loff_t pos,int size,void *data) if (llseek(fd,pos,0) != pos) pdie("Seek to %lld",pos); if ((got = read(fd,data,size)) < 0) pdie("Read %d bytes at %lld",size,pos); #endif // TMN: - if (got != size) die("Got %d bytes instead of %d at %lld",got,size,pos); + if (got != size) die("Got %d bytes instead of %d at %I64d",got,size,pos); for (walk = changes; walk; walk = walk->next) { if (walk->pos < pos+size && walk->pos+walk->size > pos) { if (walk->pos < pos) @@ -166,32 +161,52 @@ void fs_write(loff_t pos,int size,void *data) int did; #if 1 //SAE - void *scratch; - const size_t readsize_aligned = (size % 512) ? (size + (512 - (size % 512))) : size; - const loff_t seekpos_aligned = pos - (pos % 512); - const size_t seek_delta = (size_t)(pos - seekpos_aligned); - const size_t readsize = (size_t)(pos - seekpos_aligned) + readsize_aligned; - scratch = alloc(readsize_aligned); - if (write_immed) { - did_change = 1; - if (llseek(fd,seekpos_aligned,0) != seekpos_aligned) pdie("Seek to %lld",pos); - if ((did = write(fd,data,readsize_aligned)) == (int)readsize_aligned) - { - free(scratch); - return; - } - if (did < 0) pdie("Write %d bytes at %lld",size,pos); - die("Wrote %d bytes instead of %d at %lld",did,size,pos); - } - new = alloc(sizeof(CHANGE)); - new->pos = pos; - memcpy(new->data = alloc(new->size = readsize_aligned),data,readsize_aligned); - new->next = NULL; - if (last) last->next = new; - else changes = new; - last = new; + void *scratch; + const size_t readsize_aligned = (size % 512) ? (size + (512 - (size % 512))) : size; + const loff_t seekpos_aligned = pos - (pos % 512); + const size_t seek_delta = (size_t)(pos - seekpos_aligned); + const size_t readsize = (size_t)(pos - seekpos_aligned) + readsize_aligned; + boolean use_read = (seek_delta != 0) || ((readsize_aligned-size) != 0); + /* Aloc temp buffer if write is not aligned */ + if (use_read) + scratch = alloc(readsize_aligned); + else + scratch = data; + + did_change = 1; + if (llseek(fd,seekpos_aligned,0) != seekpos_aligned) pdie("Seek to %I64d",seekpos_aligned); + + if (use_read) + { + /* Read aligned data */ + if (read(fd,scratch,readsize_aligned) < 0) pdie("Read %d bytes at %I64d",size,pos); + + /* Patch data in memory */ + memcpy(data, scratch+seek_delta, size); + } + + /* Write it back */ + if ((did = write(fd,scratch,readsize_aligned)) == (int)readsize_aligned) + { + if (use_read) free(scratch); + return; + } + if (did < 0) pdie("Write %d bytes at %I64d",size,pos); + die("Wrote %d bytes instead of %d at %I64d",did,size,pos); + } + + if (!no_change_list) + { + new = alloc(sizeof(CHANGE)); + new->pos = pos; + memcpy(new->data = alloc(new->size = size),data,size); + new->next = NULL; + if (last) last->next = new; + else changes = new; + last = new; + } #else //SAE if (write_immed) { did_change = 1; @@ -215,10 +230,16 @@ static void fs_flush(void) { CHANGE *this; int size; + int old_write_immed = write_immed; + + /* Disable writes to the list now */ + no_change_list = 1; + write_immed = 1; while (changes) { this = changes; changes = changes->next; +#if 0 if (llseek(fd,this->pos,0) != this->pos) fprintf(stderr,"Seek to %lld failed: %s\n Did not write %d bytes.\n", (__int64)this->pos,strerror(errno),this->size); @@ -228,9 +249,17 @@ static void fs_flush(void) else if (size != this->size) fprintf(stderr,"Wrote %d bytes instead of %d bytes at %lld." "\n",size,this->size,(__int64)this->pos); +#else + fs_write(this->pos, this->size, this->data); +#endif + free(this->data); free(this); } + + /* Restore values */ + no_change_list = 0; + write_immed = old_write_immed; }