public inbox for linux-mtd@lists.infradead.org
 help / color / mirror / Atom feed
From: Jean Pihet <jpihet@mvista.com>
To: linux-mtd@lists.infradead.org
Cc: nickpiggin@yahoo.com.au, joern@logfs.org, dwmw2@infradead.org,
	Alexey Korolev <akorolev@infradead.org>,
	akpm@linux-foundation.org
Subject: Re: [BUG] JFFS2 usage of write_begin and write_end functions causes kernel panic
Date: Thu, 10 Apr 2008 19:18:21 +0200	[thread overview]
Message-ID: <200804101918.21362.jpihet@mvista.com> (raw)
In-Reply-To: <Pine.LNX.4.64.0804101152270.13226@pentafluge.infradead.org>

[-- Attachment #1: Type: text/plain, Size: 7612 bytes --]

Alexey,

Here is the patch (attached) I applied to get a stable JFFS2 filesystem.
The changes have been cherry picked from 
http://sourceforge.net/projects/mtd-mods.

I stressed it with intensive read/write, flash fill-up and data removal. A few 
GB's of data have been transferred without any problem. I didn't try the tool 
you mentionned though.
Tested on OMAP3 platform.

Now I am testing with PREEMPT_RT config.

Regards,
Jean.

On Thursday 10 April 2008 18:53:55 Alexey Korolev wrote:
> Hi all,
>
> We faced JFFS2 kernel panic issues on Linux 2.6.24.
> Bug is easy reproducible if to perform random file system operations
> (esepcially trunkate). We have made a trivial tool which reproduces the
> problem on JFFS2 partiton. Usually less than 10 min is needed to catch a
> panic.
>
> The problem is related to introduction  of write_begin and write_end
> functions instead of original prepare_write & commit_write. The kernel
> panic has disappeared when we rolled back write_begin and write_end changes
> in JFFS2. We tried to fix it - but it seems problem is bit tough for us. I
> would be much appreciate if someone would fix the problem or suggest where
> the problem is. We made several attempts to identify the source but still
> have not idea about what exactly is the source of the bug. Each time panic
> messages are different.
>
> Here is the log of one of kernel panic messages:
>
> 4/103: write f0 [915918,86035] 28
> 4/104: unlink d3/d6/df/f16 0
> 4/106: getdents d3 0
> 4/107: write d3/d6/fd [1352490,60815] 28
> 10/209: truncate d5/f9 1534232 28
> 10/210Unable to handle kernel NULL pointer dereference at virtual
> address 000000
> 00
>
> : chown d5/df/d12/d1e 156 28
>
> 10/211: rename d5/df/d10/d15/f18 tpgd = c310c000
> o d5/d20/f3c 28
> 10/212: mkdir d5/df/d10/d15/d28/d3d 28
> 10/213:[00000000] *pgd=a3107031 creat d5/df/d10/d15/f3e x:0 28 0
> 10/214: fsync d5/df/d10/d15/d, *pte=000000001b/f22 0
> 10/215: rename d5/df/d12/d1e to d5/df/d12/d3f 28
> 10/2, *ppte=0000000016: readlink - no filename
> 10/217: write d5/df/f1c [484960,1048
> 83] 28
> 10/218: readlink - no filename
> 87/134: mkdir d3/d8/d32 Internal error: Oops: 817 [#7]
> Modules linked in:
> CPU: 0    Tainted: G      D  (2.6.24.2-pxa27x #18)
> PC is at shrink_dcache_parent+0x6c/0x108
> LR is at __init_begin+0x3fff8000/0x34
> pc : [<c008bdbc>]    lr : [<00000000>]    psr: 00000013
> sp : c310becc  ip : c3b00324  fp : c310bef4
> r10: c3b00358  r9 : 00000000  r8 : c021403c
> r7 : c0214010  r6 : c310a000  r5 : c383781c  r4 : 0000000b
> r3 : 00000000  r2 : 00000000  r1 : c3b00348  r0 : c383781c
> Flags: nzcv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
> Control: 0000397f  Table: a310c000  DAC: 00000015
> Process fsstress (pid: 825, stack limit = 0xc310a268)
> Stack: (0xc310becc to 0xc310c000)
> bec0:                            c383781c 00000000 c3838098 c310bf28
> c001e004 bee0: c310a000 0000f510 c310bf08 c310bef8 c0082d80 c008bd5c
> c383781c c310bf24 bf00: c310bf0c c00830f4 c0082d3c c383781c 00000000
> c3fba000 c310bf94 c310bf28 bf20: c0084ff0 c00830b0 c3837e68 c3c0d120
> 00031837 00000002 c3fba000 00000010 bf40: 00000000 00000000 00000006
> c001e004 c310bf6c c310bf60 c007c030 c007bd38 bf60: c310bf88 c310bf70
> c0078f58 c007c008 00000000 c30847a0 0000000a bed68de4 bf80: 0000f484
> 00000028 c310bfa4 c310bf98 c0085080 c0084f50 00000000 c310bfa8 bfa0:
> c001de60 c0085074 0000000a bed68de4 400006b0 bed689dc bed689d4 bed689dc
> bfc0: 0000000a bed68de4 0000f484 00000000 000081cc 00000000 0000f510
> bed689c4 bfe0: bed689c8 bed685a4 0000aaa0 0001ffc4 20000010 400006b0
> 00000000 00000000 Backtrace:
> [<c008bd50>] (shrink_dcache_parent+0x0/0x108) from [<c0082d80>]
> (dentry_unhash+0
> x50/0x9c)
> [<c0082d30>] (dentry_unhash+0x0/0x9c) from [<c00830f4>]
> (vfs_rmdir+0x50/0xbc)
>  r4:c383781c
> [<c00830a4>] (vfs_rmdir+0x0/0xbc) from [<c0084ff0>] (do_rmdir+0xac/0xf0)
>  r6:c3fba000 r5:00000000 r4:c383781c
> [<c0084f44>] (do_rmdir+0x0/0xf0) from [<c0085080>] (sys_rmdir+0x18/0x1c)
>  r7:00000028 r6:0000f484 r5:bed68de4 r4:0000000a
> [<c0085068>] (sys_rmdir+0x0/0x1c) from [<c001de60>]
> (ret_fast_syscall+0x0/0x2c)
> Code: e2433001 e5873004 e5912004 e59c3024 (e5823000)
> 28
>
>
> Here is a code of trivial tool which reproduces the issue very fast:
>
> /*Code is based on fsstress GPL program*/
> #define _LARGEFILE64_SOURCE
> #include <sys/stat.h>
> #include <sys/statvfs.h>
> #include <sys/time.h>
> #include <sys/ioctl.h>
> #include <sys/wait.h>
> #include <sys/types.h>
> #include <fcntl.h>
> #include <malloc.h>
> #include <dirent.h>
> #include <errno.h>
> #include <string.h>
> #include <stdlib.h>
> #include <stdio.h>
> #include <unistd.h>
> #include <error.h>
>
> #define MAX_FILE_NAME_LEN 256
> #define FILE_MASK "file"
> #define MNT_POINT "/mnt/mtd8/"
> #define BUF_SIZE (128*1024)
>
> char rnd_buf[BUF_SIZE];
> int files_created;
> char mnt_pnt[256];
>
> enum ops
> {
>   OPS_CREAT,
>   OPS_WRITE,
>   OPS_TRUNC,
>   OPS_TOTAL
> };
>
> void creat_f()
> {
>   int fd;
>   char fname[MAX_FILE_NAME_LEN];
>   sprintf(fname,"%s%s.%d",mnt_pnt,FILE_MASK,files_created);
>   printf("creat fname=%s\n",fname);
>   fd=creat(fname,0666);
>   if(!fd)
> 	return;
>   close(fd);
>   files_created++;
> }
>
> void write_f(int file_num)
> {
>   printf("write file_num:%d\n",file_num);
>   struct stat64 stb;
>   int fd;
>   __int64_t lr = ((__int64_t)random() << 32) + random();
>   off64_t writeofft=0;
>   long writelen=0;
>   char fname[MAX_FILE_NAME_LEN];
>   sprintf(fname,"%s%s.%d",mnt_pnt,FILE_MASK,file_num);
>
>   fd=open(fname,O_WRONLY);
>   if(!fd)
> 	return;
>   if(fstat64(fd,&stb)<0)
>   {
> 	close(fd);
> 	return;
>   }
>   printf("stb.st_size=%lld\n",stb.st_size);
>   if(stb.st_size!=0)
> 	writeofft=(off64_t)(lr%(stb.st_size + BUF_SIZE*4));
>   writelen=random()%BUF_SIZE;
>   if(writeofft!=lseek64(fd,writeofft,SEEK_SET))
>   {
> 	printf("lseek64 failed with errno %d
> %s\n",errno,strerror(errno));
> 	return;
>   }
>   memset(rnd_buf,(file_num%127)&0xFF,BUF_SIZE);
>   printf("fname=%s writeofft=%lld
> writelen=%ld\n",fname,writeofft,writelen);
>   write(fd,rnd_buf,writelen);
>   printf("after write\n");
>   close(fd);
> }
>
> void trunc_f(int file_num)
> {
>   printf("trunc file_num:%d\n",file_num);
>   int fd;
>   struct stat64 stb;
>   stb.st_size=0;
>   __int64_t lr = ((__int64_t)random() << 32) + random();
>   off64_t truncofft=0;
>   char fname[MAX_FILE_NAME_LEN];
>   sprintf(fname,"%s%s.%d",mnt_pnt,FILE_MASK,file_num);
>   fd=open(fname,O_RDONLY);
>   if(!fd)
> 	return;
>   if(fstat64(fd,&stb)<0)
>   {
> 	close(fd);
> 	return;
>   }
>   close(fd);
>
>   truncofft=(off64_t)(lr%(stb.st_size + BUF_SIZE*4));
>   printf("fname=%s truncofft=%lld\n",fname,truncofft);
>   truncate64(fname,truncofft);
> }
>
> int main(int argc,char** argv)
> {
>   int op_num;
>   int file_num;
>   files_created=0;
>
>   if(argc != 2 || (argc==2 && (strcmp(argv[1],"--help")==0 ||
> strcmp(argv[1],"-h")==0)))
>   {
> 	printf("Using: rndops dir\n");
> 	return 0;
>   }
>   else
>   {
> 	strcpy(mnt_pnt,argv[1]);
>   }
>
>   if(mnt_pnt[strlen(mnt_pnt)-1]!='/')
> 	strcat(mnt_pnt,"/");
>
>   creat_f();
>
>   while(1)
>   {
> 	op_num=random()%OPS_TOTAL;
> 	file_num=random()%files_created;
> 	switch(op_num)
> 	{
> 	  case OPS_CREAT:
> 	  creat_f();
> 	  break;
> 	  case OPS_WRITE:
> 		write_f(file_num);
> 		break;
> 	  case OPS_TRUNC:
> 		trunc_f(file_num);
> 		break;
> 	}
>   }
>
>   return 0;
> }
>
> Thanks,
> Alexey
>
> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/



[-- Attachment #2: 0001-mtd-jffs2-Fix-non-contiguous-write-BUG-warning-abo.patch --]
[-- Type: text/x-diff, Size: 1973 bytes --]

From 04574ba1c6233a09578988d565a4cc3f2e27f723 Mon Sep 17 00:00:00 2001
From: Jean Pihet <jpihet@mvista.com>
Date: Wed, 9 Apr 2008 11:04:32 +0200
Subject: [PATCH] mtd jffs2: Fix non contiguous write BUG, warning about 'len too short'

Merged 2 fixes from mtd-jffs2-stable-linux-2.6.23 at http://sourceforge.net/projects/mtd-mods:
- non contiguous write BUG
- false warning about 'len too short'

Cf. http://sourceforge.net/project/showfiles.php?group_id=207166&package_id=261645
 for archive download

Tested with intensive (2+ GB data) simultaneous read/write, flash fill-up, data removal cycles

Signed-off-by: Jean Pihet <jpihet@mvista.com>
---
 fs/jffs2/readinode.c |    2 +-
 fs/jffs2/wbuf.c      |    4 ++++
 2 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c
index 2eae5d2..20efdda 100644
--- a/fs/jffs2/readinode.c
+++ b/fs/jffs2/readinode.c
@@ -63,7 +63,7 @@ static int check_node_data(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info
 	 * adding and jffs2_flash_read_end() interface. */
 	if (c->mtd->point) {
 		err = c->mtd->point(c->mtd, ofs, len, &retlen, &buffer);
-		if (!err && retlen < tn->csize) {
+		if (!err && retlen < len) {
 			JFFS2_WARNING("MTD point returned len too short: %zu instead of %u.\n", retlen, tn->csize);
 			c->mtd->unpoint(c->mtd, buffer, ofs, retlen);
 		} else if (err)
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c
index d1d4f27..e023511 100644
--- a/fs/jffs2/wbuf.c
+++ b/fs/jffs2/wbuf.c
@@ -888,6 +888,10 @@ int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs,
 		donelen += wbuf_retlen;
 	}
 
+	/* adjust write buffer offset, else we get a non contiguous write bug */
+	if (!(c->wbuf_ofs % c->sector_size) && !c->wbuf_len)
+		c->wbuf_ofs = 0xffffffff;
+
 	/*
 	 * If there's a remainder in the wbuf and it's a non-GC write,
 	 * remember that the wbuf affects this ino
-- 
1.5.4.1.159.gc4a6c


  reply	other threads:[~2008-04-10 17:16 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-04-10 16:53 [BUG] JFFS2 usage of write_begin and write_end functions causes kernel panic Alexey Korolev
2008-04-10 17:18 ` Jean Pihet [this message]
2008-04-10 18:35   ` Joakim Tjernlund
2008-04-10 18:51     ` Jean Pihet
2008-04-10 18:56       ` Joakim Tjernlund
2008-04-11 18:00   ` Alexey Korolev
2008-04-11 18:05     ` Artem Bityutskiy
2008-04-13 10:50       ` Jörn Engel
2008-04-13 12:42         ` David Woodhouse
2008-04-14  8:25         ` Alexander Belyakov
2008-04-12 13:31     ` Joakim Tjernlund
2008-04-12 14:48 ` David Woodhouse
2008-04-14 16:09   ` Alexey Korolev
2008-04-14 17:08     ` Alexey Korolev
2008-04-24 21:10       ` Anders Grafström
2008-04-24 22:15         ` David Woodhouse
2008-04-25 10:04           ` Alexey Korolev
2008-04-25 16:09           ` Anders Grafström
2008-04-26 14:52             ` David Woodhouse
2008-04-28 20:00             ` Anders Grafström

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200804101918.21362.jpihet@mvista.com \
    --to=jpihet@mvista.com \
    --cc=akorolev@infradead.org \
    --cc=akpm@linux-foundation.org \
    --cc=dwmw2@infradead.org \
    --cc=joern@logfs.org \
    --cc=linux-mtd@lists.infradead.org \
    --cc=nickpiggin@yahoo.com.au \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox