Re: [Yaffs] Weird RandomAccessFile behavior on Android

Top Page
Attachments:
Message as email
+ (text/plain)
Delete this message
Reply to this message
Author: Charles Manning
Date:  
To: yaffs
Subject: Re: [Yaffs] Weird RandomAccessFile behavior on Android
On Wednesday 24 November 2010 11:34:34 Charles Manning wrote:
> On Wednesday 24 November 2010 10:43:42 Bob Lee wrote:
> > YAFFS team,
> >
> > After investigating some corrupt files in our Android app, I think I've
> > narrowed the problem down to YAFFS. The same code on a FAT fs performs as
> > expected.
> >
> > First, it looks like RandomAccessFile.setLength(), which translates to
> > ftruncate(), can fail silently. For example, I can set the file length to
> > much more space than is available, and I don't get an error.
>
> AFAIK, FAT and yaffs are different in how they handle truncate and friends.
>
> AFAIK, FAT does not generate sparse files. If you truncate up or seek past
> the file extents and then write, FAT will fill the file with 0x00 bytes.
>
> YAFFS generates sparse files. If you don't actually write data then none is
> stored. The file has a "hole" which reads back as zero bytes.
>
> Thus, yaffs is likely truncating without writing data and is thus not
> failing.
>
> > I'm not sure
> > why else ftruncate() fails, but we've seen cases where the actual file
> > length (as reported by "ls -l") is less than it should
> > be.
>
> OK that sounds like a bug and I shall investigate.
> truncating a file up should return the file size, regardless of the data in
> the file.


Bob I could not reproduce this problem. Here's what I tried running the
current HEAD in yaffs2 git. This was running on a Ubuntu system.

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>


#define FNAME "foo"

void stat_dump(int h)
{
     struct stat x;
    int result;
    result = fstat(h,&x);
    if(result < 0){
                printf("stat of handle %d failed result %d\n",h,result);
        perror("fstat failed");
    } else
                  printf(" length %d\n",(int)(x.st_size));
}


main()
{
     int h;
    int r;
    unlink(FNAME);
    h = open(FNAME, O_CREAT | O_TRUNC | O_RDWR);
    printf("open: h is %d\n",h);
    stat_dump(h);


    r = ftruncate(h,12345678);
    printf("ftruncate result %d\n",r);
    stat_dump(h);
    r = lseek(h,0,SEEK_END);
    printf("lseek result %d\n",r);
}


root@charles-laptop:/mnt# ~charles//junk/check_ftruncate
open: h is 3
length 0
ftruncate result 0
length 12345678
lseek result 12345678

After creation the file length is zero.
After ftruncate it is the right size.

I get exactly the same running on ext2.


What version of Android are you running?

-- Charles