infinite loop in jffs2_flush_wbuf_gc()?

Artem B. Bityuckiy dedekind at yandex.ru
Thu Jul 14 13:14:32 EDT 2005


Rick,

sorry for long delay in my reply, I've forgotten about you :-(

'cvs log gc.c' has the following entry:
----------------------------
revision 1.146
date: 2005/03/20 17:45:25;  author: dedekind;  state: Exp;  lines: +7 -1
Make sure the erase_pending_wbuf_list's blocks are taken into account
when picking the block to GC.
----------------------------

This was the fix of the endless GC bug. Probably this is what you faced. 
May be there was one more modified file, don't remember, probably 
wbuf.c. You may find this out if you may use cvs. Try to make the same 
changes.

AFAIR, the bug was easily reproduced if you unlink a file then fsync it. 
I've even found the test for you (don't mind - it isn't nice):

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

#define JFFS2_SUPER_MAGIC 0x72b6

#define FNAME "tmp"

void print_jffs_stat(char *path, struct statfs *fsinfo){
     if (statfs(path, fsinfo) == -1){
	perror("statfs() failed"); exit(1);
     }
     if (fsinfo->f_type != JFFS2_SUPER_MAGIC){
	fprintf(stderr, "%s is not jffs2 file system\n", path); exit(1);
     }
     printf("--- JFFS2 stat ---\n");
     printf("f_bsize   = %d\n", fsinfo->f_bsize);
     printf("f_blocks  = %d\n", fsinfo->f_blocks);
     printf("f_bfree   = %d\n", fsinfo->f_bfree);
     printf("f_bavail  = %d\n", fsinfo->f_bavail);
     printf("f_files   = %d\n", fsinfo->f_files);
     printf("f_ffree   = %d\n", fsinfo->f_ffree);
     printf("f_fsid    = %d\n", fsinfo->f_fsid);
     printf("f_namelen = %d\n", fsinfo->f_namelen);
}

int main(int argc, char *argv[]){
     if (argc < 1){
	fprintf(stderr, "%s jffs_root\n", argv[0]); return 1;
     }
     if (chdir(argv[1]) == -1){
	perror("chdir to jffs2 root failed"); return 1;
     }

     struct statfs fsinfo;
     struct stat   fdinfo;

     /* get initial jffs2 stat */
     print_jffs_stat(argv[1], &fsinfo);

     int		i, fd, cnt;
     off_t	pos;
     char	buf[fsinfo.f_bsize];

     printf("\ncreate file filled by zero with size more then flash\n");
     printf("it should fit flash since it maybe compressed perfectly\n");
     bzero(buf, fsinfo.f_bsize);

     if ((fd = open(FNAME, O_WRONLY | O_CREAT, 0664)) == -1){
	perror("can't open temporary file"); return 1;
     }
     unlink(FNAME);

     for(i = 0; i < fsinfo.f_blocks ; i++){
	cnt = write(fd, buf, fsinfo.f_bsize);
	if (cnt != fsinfo.f_bsize){
	    fprintf(stderr, "write to tmp file failed\n"); return 1;
	}
     }

     printf("\nfill the file with random data. Now in should not fit on 
flash\n");
     printf("so the error 'No space left on device' should appear\n");
     srand(1); for(i = 0; i < fsinfo.f_bsize; i++) buf[i] = rand();

     pos = lseek(fd, 0, SEEK_SET);
     if (pos == (off_t)-1){
	perror("lseek failed"); return 1;
     }

     for(i = 0; i < fsinfo.f_blocks ; i++){
	cnt = write(fd, buf, fsinfo.f_bsize);
	if (cnt != fsinfo.f_bsize) break;
     }
     if ((cnt != -1)||(errno != ENOSPC)){
	perror("Warning!!! Expected ENOSPC:"); return 1;
     }
     fsync(fd);
     printf("Ok. ENOSPC occured. Thats fine!\n");

     close(fd);
}

-- 
Best Regards,
Artem B. Bityuckiy,
St.-Petersburg, Russia.




More information about the linux-mtd mailing list