public inbox for linux-xfs@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] xfs_repair: junk last entry in sf dir if name starts beyond dir size
@ 2015-03-09 20:13 Eric Sandeen
  2015-03-10  1:17 ` Brian Foster
  2015-03-10 17:27 ` Rui Gomes
  0 siblings, 2 replies; 12+ messages in thread
From: Eric Sandeen @ 2015-03-09 20:13 UTC (permalink / raw)
  To: Rui Gomes, xfs-oss

When process_sf_dir2() is trying to salvage entries in a corrupted
short form directory, it may attempt to shorten the last entry in
the dir if it extends beyond the directory size.

However, if the name already starts past the dir size, no amount
of name-shortening will make it fit, but the code doesn't realize
this.  The namelen variable comes out to be negative, and things
go downhill from there, resulting in a segfault when we try to
memmove a negative number of bytes.

If no amount of name-shortening can make the last dir entry fit
in the dir size, simply junk the entry.

Reported by: Rui Gomes <rgomes@rvx.is>
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
---

This adds a bit more spaghetti to an existing pot, but I think
it clearly fixes the problem; I might try to rework these cases
to coalesce some of the code.

(I also wonder about the tradeoff between shortening entries and
increasing the dir size, but for now I'm just following the
direction the repair code already takes).

diff --git a/repair/dir2.c b/repair/dir2.c
index 6b8964d..308808d 100644
--- a/repair/dir2.c
+++ b/repair/dir2.c
@@ -911,6 +911,20 @@ _("zero length entry in shortform dir %" PRIu64 ""),
 				namelen = ino_dir_size -
 					((__psint_t) &sfep->name[0] -
 					 (__psint_t) sfp);
+				/* Entry name starts past size of dir; junk it */
+				if (namelen <= 0) {
+					do_warn(
+_("start of last entry name overflows space left in in shortform dir %" PRIu64 ", "),
+						ino);
+					if (!no_modify)
+						do_warn(
+						_("junking entry #%d\n"), i);
+					else
+						do_warn(
+						_("would junk entry #%d\n"), i);
+					break;
+				}
+				/* Ok, truncate this entry to end of dir */
 				do_warn(
 _("size of last entry overflows space left in in shortform dir %" PRIu64 ", "),
 					ino);

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

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

* Re: [PATCH] xfs_repair: junk last entry in sf dir if name starts beyond dir size
  2015-03-09 20:13 [PATCH] xfs_repair: junk last entry in sf dir if name starts beyond dir size Eric Sandeen
@ 2015-03-10  1:17 ` Brian Foster
  2015-03-10 13:27   ` Eric Sandeen
  2015-03-10 17:27 ` Rui Gomes
  1 sibling, 1 reply; 12+ messages in thread
From: Brian Foster @ 2015-03-10  1:17 UTC (permalink / raw)
  To: Eric Sandeen; +Cc: Rui Gomes, xfs-oss

On Mon, Mar 09, 2015 at 04:13:16PM -0400, Eric Sandeen wrote:
> When process_sf_dir2() is trying to salvage entries in a corrupted
> short form directory, it may attempt to shorten the last entry in
> the dir if it extends beyond the directory size.
> 
> However, if the name already starts past the dir size, no amount
> of name-shortening will make it fit, but the code doesn't realize
> this.  The namelen variable comes out to be negative, and things
> go downhill from there, resulting in a segfault when we try to
> memmove a negative number of bytes.
> 
> If no amount of name-shortening can make the last dir entry fit
> in the dir size, simply junk the entry.
> 
> Reported by: Rui Gomes <rgomes@rvx.is>
> Signed-off-by: Eric Sandeen <sandeen@redhat.com>
> ---
> 
> This adds a bit more spaghetti to an existing pot, but I think
> it clearly fixes the problem; I might try to rework these cases
> to coalesce some of the code.
> 
> (I also wonder about the tradeoff between shortening entries and
> increasing the dir size, but for now I'm just following the
> direction the repair code already takes).
> 

Seems Ok on a first glance. The fix is associated with the specific
namelen calculation. Are we susceptible to a similar problem in the
previous branch where we also calculate namelen from the dir size (the
namelen == 0 case)? It looks like we could set a bad value there.

Brian

> diff --git a/repair/dir2.c b/repair/dir2.c
> index 6b8964d..308808d 100644
> --- a/repair/dir2.c
> +++ b/repair/dir2.c
> @@ -911,6 +911,20 @@ _("zero length entry in shortform dir %" PRIu64 ""),
>  				namelen = ino_dir_size -
>  					((__psint_t) &sfep->name[0] -
>  					 (__psint_t) sfp);
> +				/* Entry name starts past size of dir; junk it */
> +				if (namelen <= 0) {
> +					do_warn(
> +_("start of last entry name overflows space left in in shortform dir %" PRIu64 ", "),
> +						ino);
> +					if (!no_modify)
> +						do_warn(
> +						_("junking entry #%d\n"), i);
> +					else
> +						do_warn(
> +						_("would junk entry #%d\n"), i);
> +					break;
> +				}
> +				/* Ok, truncate this entry to end of dir */
>  				do_warn(
>  _("size of last entry overflows space left in in shortform dir %" PRIu64 ", "),
>  					ino);
> 
> _______________________________________________
> xfs mailing list
> xfs@oss.sgi.com
> http://oss.sgi.com/mailman/listinfo/xfs

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

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

* Re: [PATCH] xfs_repair: junk last entry in sf dir if name starts beyond dir size
  2015-03-10  1:17 ` Brian Foster
@ 2015-03-10 13:27   ` Eric Sandeen
  2015-03-10 15:43     ` Eric Sandeen
  0 siblings, 1 reply; 12+ messages in thread
From: Eric Sandeen @ 2015-03-10 13:27 UTC (permalink / raw)
  To: Brian Foster; +Cc: Rui Gomes, xfs-oss

On 3/9/15 9:17 PM, Brian Foster wrote:
> On Mon, Mar 09, 2015 at 04:13:16PM -0400, Eric Sandeen wrote:
>> When process_sf_dir2() is trying to salvage entries in a corrupted
>> short form directory, it may attempt to shorten the last entry in
>> the dir if it extends beyond the directory size.
>>
>> However, if the name already starts past the dir size, no amount
>> of name-shortening will make it fit, but the code doesn't realize
>> this.  The namelen variable comes out to be negative, and things
>> go downhill from there, resulting in a segfault when we try to
>> memmove a negative number of bytes.
>>
>> If no amount of name-shortening can make the last dir entry fit
>> in the dir size, simply junk the entry.
>>
>> Reported by: Rui Gomes <rgomes@rvx.is>
>> Signed-off-by: Eric Sandeen <sandeen@redhat.com>
>> ---
>>
>> This adds a bit more spaghetti to an existing pot, but I think
>> it clearly fixes the problem; I might try to rework these cases
>> to coalesce some of the code.
>>
>> (I also wonder about the tradeoff between shortening entries and
>> increasing the dir size, but for now I'm just following the
>> direction the repair code already takes).
>>
> 
> Seems Ok on a first glance. The fix is associated with the specific
> namelen calculation. Are we susceptible to a similar problem in the
> previous branch where we also calculate namelen from the dir size (the
> namelen == 0 case)? It looks like we could set a bad value there.

Hum, yes, I guess so ("namelen == 0" kind of threw me off).

I'll see how to handle that w/o more cut & paste.

-Eric

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

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

* Re: [PATCH] xfs_repair: junk last entry in sf dir if name starts beyond dir size
  2015-03-10 13:27   ` Eric Sandeen
@ 2015-03-10 15:43     ` Eric Sandeen
  0 siblings, 0 replies; 12+ messages in thread
From: Eric Sandeen @ 2015-03-10 15:43 UTC (permalink / raw)
  To: Brian Foster; +Cc: Rui Gomes, xfs-oss

On 3/10/15 9:27 AM, Eric Sandeen wrote:
> On 3/9/15 9:17 PM, Brian Foster wrote:
>> On Mon, Mar 09, 2015 at 04:13:16PM -0400, Eric Sandeen wrote:
>>> When process_sf_dir2() is trying to salvage entries in a corrupted
>>> short form directory, it may attempt to shorten the last entry in
>>> the dir if it extends beyond the directory size.
>>>
>>> However, if the name already starts past the dir size, no amount
>>> of name-shortening will make it fit, but the code doesn't realize
>>> this.  The namelen variable comes out to be negative, and things
>>> go downhill from there, resulting in a segfault when we try to
>>> memmove a negative number of bytes.
>>>
>>> If no amount of name-shortening can make the last dir entry fit
>>> in the dir size, simply junk the entry.
>>>
>>> Reported by: Rui Gomes <rgomes@rvx.is>
>>> Signed-off-by: Eric Sandeen <sandeen@redhat.com>
>>> ---
>>>
>>> This adds a bit more spaghetti to an existing pot, but I think
>>> it clearly fixes the problem; I might try to rework these cases
>>> to coalesce some of the code.
>>>
>>> (I also wonder about the tradeoff between shortening entries and
>>> increasing the dir size, but for now I'm just following the
>>> direction the repair code already takes).
>>>
>>
>> Seems Ok on a first glance. The fix is associated with the specific
>> namelen calculation. Are we susceptible to a similar problem in the
>> previous branch where we also calculate namelen from the dir size (the
>> namelen == 0 case)? It looks like we could set a bad value there.
> 
> Hum, yes, I guess so ("namelen == 0" kind of threw me off).
> 
> I'll see how to handle that w/o more cut & paste.

Hohum, another related bug in this code is that it isn't handling
dir3; this whole business of adjusting namelen to match end of dir
doesn't take into account that with dir3, a file type and an inode
number follow the name.

So for example when fixing a 0-length entry, it does:

> entry "" in shortform directory 67 references invalid inode 1650614882
> entry #1 is zero length in shortform dir 67, resetting to 29
> entry contains illegal character in shortform dir 67
> junking entry "bbbbbbbbbbbbbbbbbbbbbbbb" in directory inode 67

where the actual entry length should be 24, and I think the rest is
filetype etc; this is why it thought there were bogus chars and
ended up junking it all.

Something else to fix...

-Eric

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

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

* Re: [PATCH] xfs_repair: junk last entry in sf dir if name starts beyond dir size
  2015-03-09 20:13 [PATCH] xfs_repair: junk last entry in sf dir if name starts beyond dir size Eric Sandeen
  2015-03-10  1:17 ` Brian Foster
@ 2015-03-10 17:27 ` Rui Gomes
  2015-03-10 17:37   ` Eric Sandeen
  1 sibling, 1 reply; 12+ messages in thread
From: Rui Gomes @ 2015-03-10 17:27 UTC (permalink / raw)
  To: Eric Sandeen; +Cc: xfs

Hello Eric, 

I clone the xfs git "git://oss.sgi.com/xfs/cmds/xfsprogs" and I couldn't find the code in any of the branch's
Is the code in a public available git?

Regards 

------------------------------- 
Rui Gomes 
CTO 


RVX - Reykjavik Visual Effects 
Seljavegur 2, 
101 Reykjavik 
Iceland 


Tel: + 354 527 3330 
Mob: + 354 663 3360

----- Original Message -----
From: "Eric Sandeen" <sandeen@sandeen.net>
To: "Rui Gomes" <rgomes@rvx.is>, "xfs" <xfs@oss.sgi.com>
Sent: Monday, 9 March, 2015 20:13:16
Subject: [PATCH] xfs_repair: junk last entry in sf dir if name starts beyond dir size

When process_sf_dir2() is trying to salvage entries in a corrupted
short form directory, it may attempt to shorten the last entry in
the dir if it extends beyond the directory size.

However, if the name already starts past the dir size, no amount
of name-shortening will make it fit, but the code doesn't realize
this.  The namelen variable comes out to be negative, and things
go downhill from there, resulting in a segfault when we try to
memmove a negative number of bytes.

If no amount of name-shortening can make the last dir entry fit
in the dir size, simply junk the entry.

Reported by: Rui Gomes <rgomes@rvx.is>
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
---

This adds a bit more spaghetti to an existing pot, but I think
it clearly fixes the problem; I might try to rework these cases
to coalesce some of the code.

(I also wonder about the tradeoff between shortening entries and
increasing the dir size, but for now I'm just following the
direction the repair code already takes).

diff --git a/repair/dir2.c b/repair/dir2.c
index 6b8964d..308808d 100644
--- a/repair/dir2.c
+++ b/repair/dir2.c
@@ -911,6 +911,20 @@ _("zero length entry in shortform dir %" PRIu64 ""),
 				namelen = ino_dir_size -
 					((__psint_t) &sfep->name[0] -
 					 (__psint_t) sfp);
+				/* Entry name starts past size of dir; junk it */
+				if (namelen <= 0) {
+					do_warn(
+_("start of last entry name overflows space left in in shortform dir %" PRIu64 ", "),
+						ino);
+					if (!no_modify)
+						do_warn(
+						_("junking entry #%d\n"), i);
+					else
+						do_warn(
+						_("would junk entry #%d\n"), i);
+					break;
+				}
+				/* Ok, truncate this entry to end of dir */
 				do_warn(
 _("size of last entry overflows space left in in shortform dir %" PRIu64 ", "),
 					ino);

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

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

* Re: [PATCH] xfs_repair: junk last entry in sf dir if name starts beyond dir size
  2015-03-10 17:27 ` Rui Gomes
@ 2015-03-10 17:37   ` Eric Sandeen
  2015-03-11 14:26     ` Rui Gomes
  0 siblings, 1 reply; 12+ messages in thread
From: Eric Sandeen @ 2015-03-10 17:37 UTC (permalink / raw)
  To: Rui Gomes; +Cc: xfs

On 3/10/15 1:27 PM, Rui Gomes wrote:
> Hello Eric, 
> 
> I clone the xfs git "git://oss.sgi.com/xfs/cmds/xfsprogs" and I couldn't find the code in any of the branch's
> Is the code in a public available git?

The latest userspae code is currently at git://git.kernel.org/pub/scm/fs/xfs/xfsprogs-dev.git

The patch I sent applies on top of that, it's not yet been committed to the repo.
The patch as sent should get you through your segfault, but we'll probably end
up merging something a bit different.

-Eric

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

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

* Re: [PATCH] xfs_repair: junk last entry in sf dir if name starts beyond dir size
  2015-03-10 17:37   ` Eric Sandeen
@ 2015-03-11 14:26     ` Rui Gomes
  2015-03-11 14:44       ` Eric Sandeen
  0 siblings, 1 reply; 12+ messages in thread
From: Rui Gomes @ 2015-03-11 14:26 UTC (permalink / raw)
  To: Eric Sandeen; +Cc: omar, xfs

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

Hello Eric,

Thank you for the quick reply yesterday, I got to try the new patched version today,
and we have now a segmentation fault at a different stage of the repair  \o/ 
Full output plus gdb traceback in the attachment.

Regards 

------------------------------- 
Rui Gomes 
CTO 


RVX - Reykjavik Visual Effects 
Seljavegur 2, 
101 Reykjavik 
Iceland 


Tel: + 354 527 3330 
Mob: + 354 663 3360

----- Original Message -----
From: "Eric Sandeen" <sandeen@sandeen.net>
To: "Rui Gomes" <rgomes@rvx.is>
Cc: "xfs" <xfs@oss.sgi.com>
Sent: Tuesday, 10 March, 2015 17:37:03
Subject: Re: [PATCH] xfs_repair: junk last entry in sf dir if name starts beyond dir size

On 3/10/15 1:27 PM, Rui Gomes wrote:
> Hello Eric, 
> 
> I clone the xfs git "git://oss.sgi.com/xfs/cmds/xfsprogs" and I couldn't find the code in any of the branch's
> Is the code in a public available git?

The latest userspae code is currently at git://git.kernel.org/pub/scm/fs/xfs/xfsprogs-dev.git

The patch I sent applies on top of that, it's not yet been committed to the repo.
The patch as sent should get you through your segfault, but we'll probably end
up merging something a bit different.

-Eric

[-- Attachment #2: xfs_gdb.txt --]
[-- Type: text/plain, Size: 3679 bytes --]

[root@icess8a repair]# gdb ./xfs_repair 
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-51.el7
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /root/xfsprogs-dev/repair/xfs_repair...done.
(gdb) run -L -P -vvv /dev/sdb1
Starting program: /root/xfsprogs-dev/repair/./xfs_repair -L -P -vvv /dev/sdb1
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
Phase 1 - find and verify superblock...
        - max_mem = 24562701, icount = 22628224, imem = 88391, dblock = 3904294144, dmem = 1906393
        - block cache size set to 2814736 entries
Phase 2 - using internal log
        - zero log...
zero_log: head block 8 tail block 8
        - scan filesystem freespace and inode maps...
[New Thread 0x7fffef950700 (LWP 7732)]
[New Thread 0x7fffef14f700 (LWP 7733)]
[New Thread 0x7fffee94e700 (LWP 7734)]
[New Thread 0x7fffee14d700 (LWP 7735)]
[New Thread 0x7fffed94c700 (LWP 7736)]
[New Thread 0x7fffed14b700 (LWP 7737)]
[New Thread 0x7fffec94a700 (LWP 7738)]
[New Thread 0x7fffec149700 (LWP 7739)]
[New Thread 0x7fffeb948700 (LWP 7740)]
[New Thread 0x7fffeb147700 (LWP 7741)]
[New Thread 0x7fffea946700 (LWP 7742)]
[New Thread 0x7fffea145700 (LWP 7743)]
[New Thread 0x7fffe9944700 (LWP 7744)]
[New Thread 0x7fffe9143700 (LWP 7745)]
[New Thread 0x7fffe8942700 (LWP 7746)]
[New Thread 0x7fffe8141700 (LWP 7747)]
[New Thread 0x7fffe7940700 (LWP 7748)]
[New Thread 0x7fffe713f700 (LWP 7749)]
[New Thread 0x7fffe693e700 (LWP 7750)]
[New Thread 0x7fffe613d700 (LWP 7751)]
[New Thread 0x7fffe593c700 (LWP 7752)]
[New Thread 0x7fffe513b700 (LWP 7753)]
[New Thread 0x7fffe493a700 (LWP 7754)]
[New Thread 0x7fffe4139700 (LWP 7755)]
[New Thread 0x7fffe3938700 (LWP 7756)]
[New Thread 0x7fffe3137700 (LWP 7757)]
[New Thread 0x7fffe2936700 (LWP 7758)]
[New Thread 0x7fffe2135700 (LWP 7759)]
[New Thread 0x7fffe1934700 (LWP 7760)]
[New Thread 0x7fffe1133700 (LWP 7761)]
[New Thread 0x7fffe0932700 (LWP 7762)]
[New Thread 0x7fffe0131700 (LWP 7763)]
SB sanity check failed
Metadata corruption detected at block 0x4ffed6d00/0x1000
Metadata corruption detected at block 0x4ffed6d08/0x1000
bad on-disk superblock 22 - inconsistent filesystem geometry information
primary/secondary superblock 22 conflict - AG superblock geometry info conflicts with filesystem geometry
zeroing unused portion of secondary superblock (AG #22)

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffeb147700 (LWP 7741)]
__memset_sse2 () at ../sysdeps/x86_64/memset.S:873
873             movdqa %xmm0,(%rdi)
(gdb) bt
#0  __memset_sse2 () at ../sysdeps/x86_64/memset.S:873
#1  0x000000000040407b in secondary_sb_wack (mp=0x7fffffffdfc0, sbuf=0x553b01a7, i=22, sb=0x7fffa00008c0) at agheader.c:313
#2  verify_set_agheader (mp=0x7fffffffdfc0, sbuf=sbuf@entry=0x7fffa0000ad0, sb=sb@entry=0x7fffa00008c0, agf=agf@entry=0x7fffa0001e00, agi=agi@entry=0x7fffa0003000, i=i@entry=22) at agheader.c:523
#3  0x0000000000427beb in scan_ag (wq=<optimized out>, agno=22, arg=0x68eb90) at scan.c:1523
#4  0x000000000042a36a in worker_thread (arg=0x7fffffffdcd0) at threads.c:46
#5  0x00007ffff77badf3 in start_thread (arg=0x7fffeb147700) at pthread_create.c:308
#6  0x00007ffff74e81ad in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:113

[-- Attachment #3: Type: text/plain, Size: 121 bytes --]

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

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

* Re: [PATCH] xfs_repair: junk last entry in sf dir if name starts beyond dir size
  2015-03-11 14:26     ` Rui Gomes
@ 2015-03-11 14:44       ` Eric Sandeen
  2015-03-11 15:04         ` Rui Gomes
  0 siblings, 1 reply; 12+ messages in thread
From: Eric Sandeen @ 2015-03-11 14:44 UTC (permalink / raw)
  To: Rui Gomes; +Cc: omar, xfs

On 3/11/15 10:26 AM, Rui Gomes wrote:
> Hello Eric,
> 
> Thank you for the quick reply yesterday, I got to try the new patched version today,
> and we have now a segmentation fault at a different stage of the repair  \o/ 
> Full output plus gdb traceback in the attachment.

If you have 4k sectors, you might need this patch from the list:

[PATCH] xfs: superblock buffers need to be sector sized

http://marc.info/?l=linux-xfs&m=142476196802097&w=2

as it's not merged yet.

-Eric

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

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

* Re: [PATCH] xfs_repair: junk last entry in sf dir if name starts beyond dir size
  2015-03-11 14:44       ` Eric Sandeen
@ 2015-03-11 15:04         ` Rui Gomes
  2015-03-11 15:46           ` Eric Sandeen
  0 siblings, 1 reply; 12+ messages in thread
From: Rui Gomes @ 2015-03-11 15:04 UTC (permalink / raw)
  To: Eric Sandeen; +Cc: omar, xfs

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

Hello Eric, 

After applying that patch I get yet another Segmentation Fault in a different place, gdb bt and output in the attachment.


Just in case this help, bellow the inode right before the segmentation fault:

xfs_db -c "inode 620507648" -c "p" /dev/sdb1 
Metadata corruption detected at block 0x4ffed6d08/0x1000
xfs_db: cannot init perag data (117). Continuing anyway.
core.magic = 0x494e
core.mode = 040755
core.version = 2
core.format = 2 (extents)
core.nlinkv2 = 3
core.onlink = 0
core.projid_lo = 0
core.projid_hi = 0
core.uid = 0
core.gid = 0
core.flushiter = 2
core.atime.sec = Fri May 16 12:21:52 2014
core.atime.nsec = 779442171
core.mtime.sec = Tue Mar 24 12:03:59 2009
core.mtime.nsec = 000000000
core.ctime.sec = Fri Feb 28 19:54:03 2014
core.ctime.nsec = 736630717
core.size = 4096
core.nblocks = 1
core.extsize = 0
core.nextents = 1
core.naextents = 0
core.forkoff = 0
core.aformat = 2 (extents)
core.dmevmask = 0
core.dmstate = 0
core.newrtbm = 0
core.prealloc = 0
core.realtime = 0
core.immutable = 0
core.append = 0
core.sync = 0
core.noatime = 0
core.nodump = 0
core.rtinherit = 0
core.projinherit = 0
core.nosymlinks = 0
core.extsz = 0
core.extszinherit = 0
core.nodefrag = 0
core.filestream = 0
core.gen = 3064228498
next_unlinked = null
u.bmx[0] = [startoff,startblock,blockcount,extentflag] 0:[0,38781727,1,0]




Regards 

------------------------------- 
Rui Gomes 
CTO 


RVX - Reykjavik Visual Effects 
Seljavegur 2, 
101 Reykjavik 
Iceland 


Tel: + 354 527 3330 
Mob: + 354 663 3360

----- Original Message -----
From: "Eric Sandeen" <sandeen@sandeen.net>
To: "Rui Gomes" <rgomes@rvx.is>
Cc: "omar" <omar@rvx.is>, "xfs" <xfs@oss.sgi.com>
Sent: Wednesday, 11 March, 2015 14:44:41
Subject: Re: [PATCH] xfs_repair: junk last entry in sf dir if name starts beyond dir size

On 3/11/15 10:26 AM, Rui Gomes wrote:
> Hello Eric,
> 
> Thank you for the quick reply yesterday, I got to try the new patched version today,
> and we have now a segmentation fault at a different stage of the repair  \o/ 
> Full output plus gdb traceback in the attachment.

If you have 4k sectors, you might need this patch from the list:

[PATCH] xfs: superblock buffers need to be sector sized

http://marc.info/?l=linux-xfs&m=142476196802097&w=2

as it's not merged yet.

-Eric

[-- Attachment #2: xfs_gdb_2.txt --]
[-- Type: text/plain, Size: 4550 bytes --]

TRUCATED:

imap claims a free inode 620334717 is in use, correcting imap and clearing inode
cleared inode 620334717
imap claims a free inode 620334718 is in use, correcting imap and clearing inode
cleared inode 620334718
bad inode format in inode 620334719
cleared inode 620334719
Metadata corruption detected at block 0x127e18f8/0x1000
bad directory block magic # 0x414f0749 in block 0 for directory inode 620507648
corrupt block 0 in directory inode 620507648
        will junk block
no . entry for directory 620507648
no .. entry for directory 620507648
problem with directory contents in inode 620507648
cleared inode 620507648

Program received signal SIGSEGV, Segmentation fault.
0x000000000044dbcd in __xfs_dir3_data_check (dp=dp@entry=0x0, bp=bp@entry=0x1538e810) at xfs_dir2_data.c:148
148                             for (i = 0; i < be32_to_cpu(btp->count); i++) {
(gdb) bt
#0  0x000000000044dbcd in __xfs_dir3_data_check (dp=dp@entry=0x0, bp=bp@entry=0x1538e810) at xfs_dir2_data.c:148
#1  0x000000000044b9ea in xfs_dir3_block_verify (bp=bp@entry=0x1538e810) at xfs_dir2_block.c:62
#2  0x000000000044bb07 in xfs_dir3_block_read_verify (bp=0x1538e810) at xfs_dir2_block.c:76
#3  0x000000000042fd83 in libxfs_readbuf_verify (ops=0x46f550 <xfs_dir3_block_buf_ops>, bp=0x1538e810) at rdwr.c:756
#4  libxfs_readbuf (btp=0x695af0, blkno=310253808, len=8, flags=0, ops=0x46f550 <xfs_dir3_block_buf_ops>) at rdwr.c:802
#5  0x000000000042ff45 in libxfs_readbuf_map (btp=<optimized out>, map=map@entry=0x7fffffffd770, nmaps=nmaps@entry=1, flags=flags@entry=0, ops=<optimized out>) at rdwr.c:846
#6  0x0000000000411885 in da_read_buf (mp=mp@entry=0x7fffffffdfd0, nex=1, bmp=<optimized out>, ops=<optimized out>) at dir2.c:122
#7  0x00000000004131d0 in process_block_dir2 (dip=0x1538ed00, dino_dirty=0x7fffffffdc00, dirname=0x468732 "", repair=<synthetic pointer>, dotdot=0x7fffffffd864, dot=0x7fffffffd860, blkmap=0x6938c0, parent=0x7fffffffdc08, 
    ino_discovery=1, ino=620507651, mp=0x7fffffffdfd0) at dir2.c:1606
#8  process_dir2 (mp=mp@entry=0x7fffffffdfd0, ino=ino@entry=620507651, dip=dip@entry=0x1538ed00, ino_discovery=ino_discovery@entry=1, dino_dirty=dino_dirty@entry=0x7fffffffdc00, dirname=dirname@entry=0x468732 "", 
    parent=parent@entry=0x7fffffffdc08, blkmap=0x6938c0) at dir2.c:2018
#9  0x00000000004112a4 in process_dinode_int (mp=mp@entry=0x7fffffffdfd0, dino=dino@entry=0x1538ed00, agno=agno@entry=0, ino=ino@entry=620507651, was_free=<optimized out>, dirty=dirty@entry=0x7fffffffdc00, 
    used=used@entry=0x7fffffffdbfc, verify_mode=verify_mode@entry=0, uncertain=uncertain@entry=0, ino_discovery=ino_discovery@entry=1, check_dups=check_dups@entry=0, extra_attr_check=extra_attr_check@entry=1, 
    isa_dir=isa_dir@entry=0x7fffffffdc04, parent=parent@entry=0x7fffffffdc08) at dinode.c:2629
#10 0x00000000004116be in process_dinode (mp=mp@entry=0x7fffffffdfd0, dino=dino@entry=0x1538ed00, agno=agno@entry=0, ino=ino@entry=620507651, was_free=<optimized out>, dirty=dirty@entry=0x7fffffffdc00, used=used@entry=0x7fffffffdbfc, 
    ino_discovery=ino_discovery@entry=1, check_dups=check_dups@entry=0, extra_attr_check=extra_attr_check@entry=1, isa_dir=isa_dir@entry=0x7fffffffdc04, parent=parent@entry=0x7fffffffdc08) at dinode.c:2737
#11 0x000000000040b77f in process_inode_chunk (mp=mp@entry=0x7fffffffdfd0, agno=agno@entry=0, first_irec=first_irec@entry=0x7fffd8712190, ino_discovery=ino_discovery@entry=1, check_dups=check_dups@entry=0, 
    extra_attr_check=extra_attr_check@entry=1, bogus=bogus@entry=0x7fffffffdc8c, num_inos=<optimized out>) at dino_chunks.c:772
#12 0x000000000040cbad in process_aginodes (mp=0x7fffffffdfd0, pf_args=pf_args@entry=0x0, agno=agno@entry=0, ino_discovery=ino_discovery@entry=1, check_dups=check_dups@entry=0, extra_attr_check=extra_attr_check@entry=1)
    at dino_chunks.c:1025
#13 0x00000000004186fe in process_ag_func (wq=0x7fffffffdd60, agno=0, arg=0x0) at phase3.c:77
#14 0x00000000004256ca in prefetch_ag_range (work=0x7fffffffdd60, start_ag=<optimized out>, end_ag=32, dirs_only=false, func=0x4186b0 <process_ag_func>) at prefetch.c:906
#15 0x000000000042582b in do_inode_prefetch (mp=mp@entry=0x7fffffffdfd0, stride=0, func=func@entry=0x4186b0 <process_ag_func>, check_cache=check_cache@entry=false, dirs_only=dirs_only@entry=false) at prefetch.c:969
#16 0x000000000041880d in process_ags (mp=0x7fffffffdfd0) at phase3.c:85
#17 phase3 (mp=mp@entry=0x7fffffffdfd0) at phase3.c:121
#18 0x0000000000403656 in main (argc=<optimized out>, argv=<optimized out>) at xfs_repair.c:789
(gdb) 

[-- Attachment #3: Type: text/plain, Size: 121 bytes --]

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

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

* Re: [PATCH] xfs_repair: junk last entry in sf dir if name starts beyond dir size
  2015-03-11 15:04         ` Rui Gomes
@ 2015-03-11 15:46           ` Eric Sandeen
  2015-03-11 16:01             ` Rui Gomes
  0 siblings, 1 reply; 12+ messages in thread
From: Eric Sandeen @ 2015-03-11 15:46 UTC (permalink / raw)
  To: Rui Gomes; +Cc: omar, xfs

On 3/11/15 11:04 AM, Rui Gomes wrote:
> Program received signal SIGSEGV, Segmentation fault.
> 0x000000000044dbcd in __xfs_dir3_data_check (dp=dp@entry=0x0, bp=bp@entry=0x1538e810) at xfs_dir2_data.c:148
> 148                             for (i = 0; i < be32_to_cpu(btp->count); i++) {
> (gdb) bt
> #0  0x000000000044dbcd in __xfs_dir3_data_check (dp=dp@entry=0x0, bp=bp@entry=0x1538e810) at xfs_dir2_data.c:148
> #1  0x000000000044b9ea in xfs_dir3_block_verify (bp=bp@entry=0x1538e810) at xfs_dir2_block.c:62

Can you do a little digging around in gdb to sort out more
about why it segfaulted?

We got a xfs_dir2_data_hdr_t from the passed-in bp w/ valid magic:

hdr = bp->b_addr;

and from that got btp:

        switch (hdr->magic) {
        case cpu_to_be32(XFS_DIR2_BLOCK_MAGIC):
                btp = xfs_dir2_block_tail_p(mp, hdr);

and this just finds an offset from hdr:

                ((char *)hdr + mp->m_dirblksize)) - 1;

but then apparently blew up when we tried to use btp:

for (i = 0; i < be32_to_cpu(btp->count); i++) {

I don't see offhand how the hdr is ok, with good magic, but an
offset from the hdr (btp) is causing a segfault.  Can you dig around
a bit more in gdb?

-Eric

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

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

* Re: [PATCH] xfs_repair: junk last entry in sf dir if name starts beyond dir size
  2015-03-11 15:46           ` Eric Sandeen
@ 2015-03-11 16:01             ` Rui Gomes
  2015-04-09 10:42               ` Rui Gomes
  0 siblings, 1 reply; 12+ messages in thread
From: Rui Gomes @ 2015-03-11 16:01 UTC (permalink / raw)
  To: Eric Sandeen; +Cc: omar, xfs

Hi,

Thank you for pointing out where to look, I will try to dissect this a bit further and report back to you. 

Regards 

------------------------------- 
Rui Gomes 
CTO 


RVX - Reykjavik Visual Effects 
Seljavegur 2, 
101 Reykjavik 
Iceland 


Tel: + 354 527 3330 
Mob: + 354 663 3360

----- Original Message -----
From: "Eric Sandeen" <sandeen@sandeen.net>
To: "Rui Gomes" <rgomes@rvx.is>
Cc: "omar" <omar@rvx.is>, "xfs" <xfs@oss.sgi.com>
Sent: Wednesday, 11 March, 2015 15:46:50
Subject: Re: [PATCH] xfs_repair: junk last entry in sf dir if name starts beyond dir size

On 3/11/15 11:04 AM, Rui Gomes wrote:
> Program received signal SIGSEGV, Segmentation fault.
> 0x000000000044dbcd in __xfs_dir3_data_check (dp=dp@entry=0x0, bp=bp@entry=0x1538e810) at xfs_dir2_data.c:148
> 148                             for (i = 0; i < be32_to_cpu(btp->count); i++) {
> (gdb) bt
> #0  0x000000000044dbcd in __xfs_dir3_data_check (dp=dp@entry=0x0, bp=bp@entry=0x1538e810) at xfs_dir2_data.c:148
> #1  0x000000000044b9ea in xfs_dir3_block_verify (bp=bp@entry=0x1538e810) at xfs_dir2_block.c:62

Can you do a little digging around in gdb to sort out more
about why it segfaulted?

We got a xfs_dir2_data_hdr_t from the passed-in bp w/ valid magic:

hdr = bp->b_addr;

and from that got btp:

        switch (hdr->magic) {
        case cpu_to_be32(XFS_DIR2_BLOCK_MAGIC):
                btp = xfs_dir2_block_tail_p(mp, hdr);

and this just finds an offset from hdr:

                ((char *)hdr + mp->m_dirblksize)) - 1;

but then apparently blew up when we tried to use btp:

for (i = 0; i < be32_to_cpu(btp->count); i++) {

I don't see offhand how the hdr is ok, with good magic, but an
offset from the hdr (btp) is causing a segfault.  Can you dig around
a bit more in gdb?

-Eric

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

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

* Re: [PATCH] xfs_repair: junk last entry in sf dir if name starts beyond dir size
  2015-03-11 16:01             ` Rui Gomes
@ 2015-04-09 10:42               ` Rui Gomes
  0 siblings, 0 replies; 12+ messages in thread
From: Rui Gomes @ 2015-04-09 10:42 UTC (permalink / raw)
  To: Eric Sandeen; +Cc: omar, xfs

Hello Eric, 

Sorry for the late late reply, I didn't had the time to dig in to this earlier.

Actually gdb was lying us, the segfault doesn't happen at:
  for (i = 0; i < be32_to_cpu(btp->count); i++) 

but a bit later at:

if (be32_to_cpu(lep[i].address) == addr &&
        be32_to_cpu(lep[i].hashval) == hash)


And the cause of the segfault is lep[i] 

So I tried:

(gdb) print lep
$1 = (xfs_dir2_leaf_entry_t *) 0xfffffffc9ac12788

p lep[0].address
Cannot access memory at address 0xfffffffc9ac12794

For what I can see the lep[0] struct doesn't exist!

The inode where this happen bellow:

[root@icess8a xfsprogs-dev]# xfs_db -c "inode 620507648" -c "p" /dev/sdb1
Metadata corruption detected at block 0x4ffed6d08/0x1000                                                                                                                                                                                     
xfs_db: cannot init perag data (117). Continuing anyway.                                                                                                                                                                                     
core.magic = 0x494e                                                                                                                                                                                                                          
core.mode = 040755                                                                                                                                                                                                                           
core.version = 2                                                                                                                                                                                                                             
core.format = 2 (extents)
core.nlinkv2 = 3
core.onlink = 0
core.projid_lo = 0
core.projid_hi = 0
core.uid = 0
core.gid = 0
core.flushiter = 2
core.atime.sec = Fri May 16 12:21:52 2014
core.atime.nsec = 779442171
core.mtime.sec = Tue Mar 24 12:03:59 2009
core.mtime.nsec = 000000000
core.ctime.sec = Fri Feb 28 19:54:03 2014
core.ctime.nsec = 736630717
core.size = 4096
core.nblocks = 1
core.extsize = 0
core.nextents = 1
core.naextents = 0
core.forkoff = 0
core.aformat = 2 (extents)
core.dmevmask = 0
core.dmstate = 0
core.newrtbm = 0
core.prealloc = 0
core.realtime = 0
core.immutable = 0
core.append = 0
core.sync = 0
core.noatime = 0
core.nodump = 0
core.rtinherit = 0
core.projinherit = 0
core.nosymlinks = 0
core.extsz = 0
core.extszinherit = 0
core.nodefrag = 0
core.filestream = 0
core.gen = 3064228498
next_unlinked = null
u.bmx[0] = [startoff,startblock,blockcount,extentflag] 0:[0,38781727,1,0]


Regards 

------------------------------- 
Rui Gomes 
CTO 


RVX - Reykjavik Visual Effects 
Seljavegur 2, 
101 Reykjavik 
Iceland 


Tel: + 354 527 3330 
Mob: + 354 663 3360

----- Original Message -----
From: "Rui Gomes" <rgomes@rvx.is>
To: "Eric Sandeen" <sandeen@sandeen.net>
Cc: "omar" <omar@rvx.is>, "xfs" <xfs@oss.sgi.com>
Sent: Wednesday, 11 March, 2015 16:01:10
Subject: Re: [PATCH] xfs_repair: junk last entry in sf dir if name starts beyond dir size

Hi,

Thank you for pointing out where to look, I will try to dissect this a bit further and report back to you. 

Regards 

------------------------------- 
Rui Gomes 
CTO 


RVX - Reykjavik Visual Effects 
Seljavegur 2, 
101 Reykjavik 
Iceland 


Tel: + 354 527 3330 
Mob: + 354 663 3360

----- Original Message -----
From: "Eric Sandeen" <sandeen@sandeen.net>
To: "Rui Gomes" <rgomes@rvx.is>
Cc: "omar" <omar@rvx.is>, "xfs" <xfs@oss.sgi.com>
Sent: Wednesday, 11 March, 2015 15:46:50
Subject: Re: [PATCH] xfs_repair: junk last entry in sf dir if name starts beyond dir size

On 3/11/15 11:04 AM, Rui Gomes wrote:
> Program received signal SIGSEGV, Segmentation fault.
> 0x000000000044dbcd in __xfs_dir3_data_check (dp=dp@entry=0x0, bp=bp@entry=0x1538e810) at xfs_dir2_data.c:148
> 148                             for (i = 0; i < be32_to_cpu(btp->count); i++) {
> (gdb) bt
> #0  0x000000000044dbcd in __xfs_dir3_data_check (dp=dp@entry=0x0, bp=bp@entry=0x1538e810) at xfs_dir2_data.c:148
> #1  0x000000000044b9ea in xfs_dir3_block_verify (bp=bp@entry=0x1538e810) at xfs_dir2_block.c:62

Can you do a little digging around in gdb to sort out more
about why it segfaulted?

We got a xfs_dir2_data_hdr_t from the passed-in bp w/ valid magic:

hdr = bp->b_addr;

and from that got btp:

        switch (hdr->magic) {
        case cpu_to_be32(XFS_DIR2_BLOCK_MAGIC):
                btp = xfs_dir2_block_tail_p(mp, hdr);

and this just finds an offset from hdr:

                ((char *)hdr + mp->m_dirblksize)) - 1;

but then apparently blew up when we tried to use btp:

for (i = 0; i < be32_to_cpu(btp->count); i++) {

I don't see offhand how the hdr is ok, with good magic, but an
offset from the hdr (btp) is causing a segfault.  Can you dig around
a bit more in gdb?

-Eric

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

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

end of thread, other threads:[~2015-04-09 10:42 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-03-09 20:13 [PATCH] xfs_repair: junk last entry in sf dir if name starts beyond dir size Eric Sandeen
2015-03-10  1:17 ` Brian Foster
2015-03-10 13:27   ` Eric Sandeen
2015-03-10 15:43     ` Eric Sandeen
2015-03-10 17:27 ` Rui Gomes
2015-03-10 17:37   ` Eric Sandeen
2015-03-11 14:26     ` Rui Gomes
2015-03-11 14:44       ` Eric Sandeen
2015-03-11 15:04         ` Rui Gomes
2015-03-11 15:46           ` Eric Sandeen
2015-03-11 16:01             ` Rui Gomes
2015-04-09 10:42               ` Rui Gomes

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