public inbox for linux-mtd@lists.infradead.org
 help / color / mirror / Atom feed
* Truncated symlink on jffs2
@ 2001-12-24 14:15 Stéphane Doyon
  2001-12-27 11:51 ` David Woodhouse
  0 siblings, 1 reply; 4+ messages in thread
From: Stéphane Doyon @ 2001-12-24 14:15 UTC (permalink / raw)
  To: linux-mtd; +Cc: Stéphane Doyon

Hi,

I'm not subscribed, so please Cc me.

I must be missing something, I find it hard to believe that no one would 
have noticed this before... but I couldn't find any reference to this.

I wanted to backup my Compaq iPaq's flash. Using kernel 2.4.16-rmk1-hh5, 
but also happens on earlier versions. I used tar version 1.13.19 to backup to 
NFS.

Many (but not all) of my symlinks ended up with the target truncated to 
one character. For instance the symlinks in /lib would all point to "l". 
Absolute symlinks would point to "/".

It seems this happens only with symlinks I created on the iPaq using ln, 
while those that were created by mkfs.jffs2 are OK.

Calling readlink on the link yields the correct response. Using cp -a does 
the right thing.

Strac'ing tar, I see that it does an lstat of the symlink, and gets an 
st_size of 0. It then calls readlink with a buffer of size 1.

I was able to reproduce this on x86, kernel 2.4.17, with mtdram:
modprobe mtdram
modprobe mtdblock
mount -t jffs2 /dev/mtdblock0 /mnt
cd /mnt
ln -s abcdef ghi
/home/some_user/lstat ghi

where lstat is a tiny program that does lstat(argv[1], &st) and 
printf("size: %lu\n", st.st_size);. It outputs 0, but it should say 6 
(which it does on a symlink created on another fs).

Is this a bug or a known limitation? The fact that tar relies on lstat was 
a problem for me as I had to recreate tens of symlinks before my backup 
worked again.

Thanks for any explanation!

-- 
Stéphane Doyon
<s.doyon@videotron.ca>
http://pages.infinit.net/sdoyon/

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Truncated symlink on jffs2
  2001-12-24 14:15 Truncated symlink on jffs2 Stéphane Doyon
@ 2001-12-27 11:51 ` David Woodhouse
  2001-12-27 22:51   ` Stéphane Doyon
  0 siblings, 1 reply; 4+ messages in thread
From: David Woodhouse @ 2001-12-27 11:51 UTC (permalink / raw)
  To: Stéphane Doyon; +Cc: linux-mtd

s.doyon@videotron.ca said:
>  where lstat is a tiny program that does lstat(argv[1], &st) and
> printf("size: %lu\n", st.st_size);. It outputs 0, but it should say 6
> (which it does on a symlink created on another fs). 

> Is this a bug or a known limitation? 

Bug. Thanks for pointing it out. We should be setting i_size. Something like
this ought to do it for _new_ symlinks, although we should probably contrive
a hack for jffs2_read_inode() to make it dtrt on older filesystems too:

===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/dir.c,v
retrieving revision 1.44
diff -u -r1.44 dir.c
--- fs/jffs2/dir.c	2001/11/06 17:58:41	1.44
+++ fs/jffs2/dir.c	2001/12/27 11:50:08
@@ -542,7 +542,7 @@
 
 	f = JFFS2_INODE_INFO(inode);
 
-	ri->dsize = ri->csize = strlen(target);
+	ri->isize = ri->dsize = ri->csize = strlen(target);
 	ri->totlen = sizeof(*ri) + ri->dsize;
 	ri->hdr_crc = crc32(0, ri, sizeof(struct jffs2_unknown_node)-4);
 



--
dwmw2

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Truncated symlink on jffs2
  2001-12-27 11:51 ` David Woodhouse
@ 2001-12-27 22:51   ` Stéphane Doyon
  2001-12-27 22:59     ` David Woodhouse
  0 siblings, 1 reply; 4+ messages in thread
From: Stéphane Doyon @ 2001-12-27 22:51 UTC (permalink / raw)
  To: David Woodhouse; +Cc: linux-mtd

On Thu, 27 Dec 2001, David Woodhouse wrote:

> 
> s.doyon@videotron.ca said:
> >  where lstat is a tiny program that does lstat(argv[1], &st) and
> > printf("size: %lu\n", st.st_size);. It outputs 0, but it should say 6
> > (which it does on a symlink created on another fs). 
> 
> > Is this a bug or a known limitation? 
> 
> Bug. Thanks for pointing it out. We should be setting i_size. Something like
> this ought to do it for _new_ symlinks, although we should probably contrive
> a hack for jffs2_read_inode() to make it dtrt on older filesystems too:
> 
> ===================================================================
> RCS file: /home/cvs/mtd/fs/jffs2/dir.c,v
> retrieving revision 1.44
> diff -u -r1.44 dir.c
> --- fs/jffs2/dir.c	2001/11/06 17:58:41	1.44
> +++ fs/jffs2/dir.c	2001/12/27 11:50:08
> @@ -542,7 +542,7 @@
>  
>  	f = JFFS2_INODE_INFO(inode);
>  
> -	ri->dsize = ri->csize = strlen(target);
> +	ri->isize = ri->dsize = ri->csize = strlen(target);
>  	ri->totlen = sizeof(*ri) + ri->dsize;
>  	ri->hdr_crc = crc32(0, ri, sizeof(struct jffs2_unknown_node)-4);
>  
> 
> 
> 
> --
> dwmw2
> 
> 
> 

OK. Well unless I'm doing something wrong, it doesn't seem to fix it for 
me: modified my kernel, made a new symlink using ln, lstat'ed it: still 
says st_size is 0.

Is the fix correct, and will it work on a 2.4.16-rmk1-hh5 kernel?

Thanks

-- 
Stéphane Doyon
<s.doyon@videotron.ca>
http://pages.infinit.net/sdoyon/

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Truncated symlink on jffs2
  2001-12-27 22:51   ` Stéphane Doyon
@ 2001-12-27 22:59     ` David Woodhouse
  0 siblings, 0 replies; 4+ messages in thread
From: David Woodhouse @ 2001-12-27 22:59 UTC (permalink / raw)
  To: Stéphane Doyon; +Cc: linux-mtd

s.doyon@videotron.ca said:
>  OK. Well unless I'm doing something wrong, it doesn't seem to fix it
> for  me: modified my kernel, made a new symlink using ln, lstat'ed it:
> still  says st_size is 0.

> Is the fix correct, and will it work on a 2.4.16-rmk1-hh5 kernel? 

Necessary, but not sufficient. It would get i_size right when you unmount 
and remount the filesystem - we need to set inode->i_size immediately too.

I've just committed the complete version to CVS, along with the workaround
to make it right for existing filesystems.

Index: dir.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/dir.c,v
retrieving revision 1.44
retrieving revision 1.45
diff -u -r1.44 -r1.45
--- dir.c	2001/11/06 17:58:41	1.44
+++ dir.c	2001/12/27 22:43:20	1.45
@@ -31,7 +31,7 @@
  * provisions above, a recipient may use your version of this file
  * under either the RHEPL or the GPL.
  *
- * $Id: dir.c,v 1.44 2001/11/06 17:58:41 dwmw2 Exp $
+ * $Id: dir.c,v 1.45 2001/12/27 22:43:20 dwmw2 Exp $
  *
  */
 
@@ -542,7 +542,7 @@
 
 	f = JFFS2_INODE_INFO(inode);
 
-	ri->dsize = ri->csize = strlen(target);
+	inode->i_size = ri->isize = ri->dsize = ri->csize = strlen(target);
 	ri->totlen = sizeof(*ri) + ri->dsize;
 	ri->hdr_crc = crc32(0, ri, sizeof(struct jffs2_unknown_node)-4);
 
Index: readinode.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/readinode.c,v
retrieving revision 1.56
retrieving revision 1.57
diff -u -r1.56 -r1.57
--- readinode.c	2001/07/26 20:32:39	1.56
+++ readinode.c	2001/12/27 22:49:46	1.57
@@ -31,7 +31,7 @@
  * provisions above, a recipient may use your version of this file
  * under either the RHEPL or the GPL.
  *
- * $Id: readinode.c,v 1.56 2001/07/26 20:32:39 dwmw2 Exp $
+ * $Id: readinode.c,v 1.57 2001/12/27 22:49:46 dwmw2 Exp $
  *
  */
 
@@ -408,6 +408,12 @@
 
 	case S_IFLNK:
 		inode->i_op = &jffs2_symlink_inode_operations;
+		/* Hack to work around broken isize in old symlink code.
+		   Remove this when dwmw2 comes to his senses and stops
+		   symlinks from being an entirely gratuitous special
+		   case. */
+		if (!inode->i_size)
+			inode->i_size = latest_node.dsize;
 		break;
 		
 	case S_IFDIR:


--
dwmw2

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2001-12-27 22:48 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2001-12-24 14:15 Truncated symlink on jffs2 Stéphane Doyon
2001-12-27 11:51 ` David Woodhouse
2001-12-27 22:51   ` Stéphane Doyon
2001-12-27 22:59     ` David Woodhouse

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox