[Yaffs-archive] [BUG] in yaffs_unlink()

Top Page
Attachments:
Message as email
+ (text/plain)
+ test-unlink.c (text/plain)
Delete this message
Reply to this message
Author: Luc Van Oostenryck
Date:  
To: yaffs
Subject: [Yaffs-archive] [BUG] in yaffs_unlink()
Hi,

I've found an undiscovered bug in yaffs_unlink():
The problem arise when CONFIG_YAFFS_DISABLE_BACKGROUND_DELETION
is defined and we unlink() the last/only (hard)link to a file,
but this file is still opened by an application
(the attached program can show this quickly).

The problem is easy to understand:
    unlink(2) call    yaffs_unlink()
    who call    yaffs_Unlink()
    who call    yaffs_UnlinkWorker()
    who call    yaffs_UnlinkFile()
    who simply delete everything related to this file:
        directory entry, object header and data.


I will look for this tomorrow (European time).

I will appreciate if you CC any mail related to this to
my stupid email address at work: <>.

--
Luc Van Oostenryck
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <stdio.h>

void show_stat(int fd)
{   struct stat buf;
    int rc;


    rc = fstat(fd, &buf);
    if (rc != 0)
    {    perror("fstat() failed");
    exit(1);
    }
    printf("nlink  = %8d\n", buf.st_nlink);
    printf("size   = %8ld\n", buf.st_size);
}


int main(void)
{   int fd;
    int n, nr;
    char buf[1];


    fd = open("in", O_RDONLY);
    if (fd == -1)
    {    perror("open(in) failed");
    exit(1);
    }
show_stat(fd);
    if (unlink("in") != 0)
    {    perror("unlink(in) failed");
    exit(1);
    }
show_stat(fd);            // !!! Crash here in fstat() !!!


    n = 0;
    while ((nr = read(fd, buf, sizeof(buf))) > 0)
    {    n += nr;
    }
    if (nr != 0)
    {    perror("read() failed");
    exit(1);
    }


    printf("readed = %8d\n\n", n);


    sleep(30);
show_stat(fd);
    close(fd);
show_stat(fd);


    return 0;
}