[ECOS] fseek on JFFS2

Jonathan Larmour jifl@eCosCentric.com
Tue Sep 26 18:45:00 GMT 2006

Andrew Lunn wrote:
>> set_position() calculates the new absolute position and calls 
>> cyg_stdio_lseek() which (with CYGPKG_FILEIO) is meant to be just a thin 
>> veneer over lseek().
> fseek() works fine. However flush_output_unlocked() does not call
> set_position() before flushing out the buffer. It seems to assume the
> file position is already in the correct position. The test case shows
> its not. What has happened is a read is made which fills the buffer
> and obviously leaves the file pointer after the end of the data just
> read. There is when a write within this buffer, which is naturally
> buffered.  The test case then does a fseek() back to the beginning of
> the file. This causes the buffer to be flushed, which just causes it
> to be written out. There is no set_position() called to seek back to
> the start of the buffer location in the file, so the data gets written
> in the wrong place. 

That doesn't seem like the right explanation. First of all, let's clarify 
nomenclature: there are two "file positions" around, the stdio file 
position which is where stdio will be reading from/writing to next, and 
thus takes into account the buffer; and the underlying file pointer, which 
is what is (or could be) passed to lseek, and is updated by read()s and 
write()s as well. I'll call these the sfp and the ufp.

What you describe above is correct as written. Here's what should be happening:
After the first read, the sfp and the ufp will be updated. The sfp should 
reflect what point was actually read to and likely corresponds to the start 
of the buffer. The ufp corresponds to the end of the buffer. During the 
write, the old read data in the buffer is emptied. After the write, there 
may be stuff pending to be flushed in the buffer or not, but regardless sfp 
should only be greater than ufp by the number of bytes in the buffer. The 
fseek should cause the buffer to be flushed. flush_output_unlocked() will 
write the buffer at the current ufp. After which sfp will equal ufp and 
then the file is seeked.

So from looking at the code, and comparing to what should happen, I think 
flush_output_unlocked is ok. Instead I think the problem is in 
Cyg_StdioStream::write(). I think the problem is that we are nuking the 
buffer but not accounting for the possibility of sfp != ufp. We need to 
reset the ufp accordingly.

I think there is a problem in this area (but for a different reason) in 
Cyg_StdioStream::read() as well.

The testcase as well as all the stdio and ramfs tests, pass with the 
attached patch which I'll check in (easiest way for you to try it :-)). Let 
me know whether you think it's ok.

It would be nice if in exchange, one of you could tidy up that testcase to 
be a proper testcase suitable to be checked in.

eCosCentric    http://www.eCosCentric.com/    The eCos and RedBoot experts
------["The best things in life aren't things."]------      Opinions==mine
-------------- next part --------------
A non-text attachment was scrubbed...
Name: stdio.fseek.bug.anoncvs.patch
Type: text/x-patch
Size: 2536 bytes
Desc: not available
URL: <http://sourceware.org/pipermail/ecos-discuss/attachments/20060926/668d4286/attachment.bin>
-------------- next part --------------
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

More information about the Ecos-discuss mailing list