2006-01-26 14:13:16

by Heiko Carstens

[permalink] [raw]
Subject: [BUG] debugfs: hard link count wrong

There seems to be a bug in debugfs: it seems it doesn't get the hard link
count right. See the output below. This happened on s390x with git tree
of today. Any ideas?

# mount

/dev/dasda1 on / type ext3 (rw)
none on /proc type proc (rw)
none on /sys type sysfs (rw)
none on /dev/pts type devpts (rw,gid=5,mode=620)
none on /sys/kernel/debug type debugfs (rw)

# cd /sys/kernel/debug/
# ls -al
total 0
drwxr-xr-x 2 root root 0 Jan 26 14:59 .
drwxr-xr-x 3 root root 0 Jan 26 14:59 ..
drwxr-xr-x 22 root root 0 Jan 26 14:59 s390dbf

# find .
.
find: WARNING: Hard link count is wrong for .: this may be a bug in your
filesystem driver. Automatically turning on find's -noleaf option.
Earlier results may have failed to include directories that should have
been searched.

# stat .

File: `.'
Size: 0 Blocks: 0 IO Block: 4096 directory
Device: 5h/5d Inode: 22 Links: 2
Access: (0755/drwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2006-01-26 15:00:26.000000000 +0100
Modify: 2006-01-26 14:59:57.000000000 +0100
Change: 2006-01-26 14:59:57.000000000 +0100

Thanks,
Heiko


2006-01-27 03:25:16

by Greg KH

[permalink] [raw]
Subject: Re: [BUG] debugfs: hard link count wrong

On Thu, Jan 26, 2006 at 03:11:42PM +0100, Heiko Carstens wrote:
> There seems to be a bug in debugfs: it seems it doesn't get the hard link
> count right. See the output below. This happened on s390x with git tree
> of today. Any ideas?

What code were you using that called debugfs? Is it in the mainline
tree?

This works just fine for me right now:

$ uname -r
2.6.16-rc1-git4

$ mount | grep debug
none on /sys/kernel/debug type debugfs (rw)

$ cd /sys/kernel/debug/
$ find .
.
./uhci
./uhci/0000:00:1d.3
./uhci/0000:00:1d.2
./uhci/0000:00:1d.1
./uhci/0000:00:1d.0

$ find --version
GNU find version 4.3.0
Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION FTS

$ stat .
File: `.'
Size: 0 Blocks: 0 IO Block: 4096 directory
Device: eh/14d Inode: 15528 Links: 2
Access: (0755/drwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2006-01-26 19:23:28.442337216 -0800
Modify: 2006-01-24 13:14:03.487515504 -0800
Change: 2006-01-24 13:14:03.487515504 -0800


thanks,

greg k-h

2006-01-27 05:56:19

by Heiko Carstens

[permalink] [raw]
Subject: Re: [BUG] debugfs: hard link count wrong

> > There seems to be a bug in debugfs: it seems it doesn't get the hard link
> > count right. See the output below. This happened on s390x with git tree
> > of today. Any ideas?
> What code were you using that called debugfs? Is it in the mainline
> tree?

It's the s390 debug feature in arch/s390/kernel/debug.c. It's completely in
the mainline tree.

> $ cd /sys/kernel/debug/
> $ find .
> .
> ./uhci
> [...]
> $ stat .
> File: `.'
> Size: 0 Blocks: 0 IO Block: 4096 directory
> Device: eh/14d Inode: 15528 Links: 2

Links should be 3, I thought? For an empty directory it's 2 and as soon as
you create a new directory in there it should be increased by 1. Therefore
it should be 3. Or am I missing something?

Btw.: my find version: "GNU find version 4.2.20".

Thanks,
Heiko

2006-01-27 06:38:07

by Greg KH

[permalink] [raw]
Subject: Re: [BUG] debugfs: hard link count wrong

On Fri, Jan 27, 2006 at 06:56:07AM +0100, Heiko Carstens wrote:
> > > There seems to be a bug in debugfs: it seems it doesn't get the hard link
> > > count right. See the output below. This happened on s390x with git tree
> > > of today. Any ideas?
> > What code were you using that called debugfs? Is it in the mainline
> > tree?
>
> It's the s390 debug feature in arch/s390/kernel/debug.c. It's completely in
> the mainline tree.
>
> > $ cd /sys/kernel/debug/
> > $ find .
> > .
> > ./uhci
> > [...]
> > $ stat .
> > File: `.'
> > Size: 0 Blocks: 0 IO Block: 4096 directory
> > Device: eh/14d Inode: 15528 Links: 2
>
> Links should be 3, I thought? For an empty directory it's 2 and as soon as
> you create a new directory in there it should be increased by 1. Therefore
> it should be 3. Or am I missing something?

Yeah, I think you are correct. But I don't see where in the debugfs
code I messed this up...

In debugfs_mkdir() we increment the parent i_nlink properly if we create
the new subdirectory, and based on other implementations like this
(usbfs), that logic seems to be correct.

Unless something is odd with creating a directory in the root of the fs.
Does the subdirectory you have created have the proper number of links?

> Btw.: my find version: "GNU find version 4.2.20".

Hm, newer versions of find don't complain about this?

thanks,

greg k-h

2006-01-27 07:04:33

by Heiko Carstens

[permalink] [raw]
Subject: Re: [BUG] debugfs: hard link count wrong

> > > Device: eh/14d Inode: 15528 Links: 2
> > Links should be 3, I thought? For an empty directory it's 2 and as soon as
> > you create a new directory in there it should be increased by 1. Therefore
> > it should be 3. Or am I missing something?
>
> Yeah, I think you are correct. But I don't see where in the debugfs
> code I messed this up...
>
> In debugfs_mkdir() we increment the parent i_nlink properly if we create
> the new subdirectory, and based on other implementations like this
> (usbfs), that logic seems to be correct.
>
> Unless something is odd with creating a directory in the root of the fs.
> Does the subdirectory you have created have the proper number of links?

Yes, everything below the debug directory itself seems to be ok.

> > Btw.: my find version: "GNU find version 4.2.20".
> Hm, newer versions of find don't complain about this?

The latest version I could find at http://ftp.gnu.org/pub/gnu/findutils/
is 4.2.27 which still complains. No, idea from where you got the 4.2.30 :)

Thank,
Heiko

2006-01-27 07:17:46

by Greg KH

[permalink] [raw]
Subject: Re: [BUG] debugfs: hard link count wrong

On Fri, Jan 27, 2006 at 08:04:23AM +0100, Heiko Carstens wrote:
> > > > Device: eh/14d Inode: 15528 Links: 2
> > > Links should be 3, I thought? For an empty directory it's 2 and as soon as
> > > you create a new directory in there it should be increased by 1. Therefore
> > > it should be 3. Or am I missing something?
> >
> > Yeah, I think you are correct. But I don't see where in the debugfs
> > code I messed this up...
> >
> > In debugfs_mkdir() we increment the parent i_nlink properly if we create
> > the new subdirectory, and based on other implementations like this
> > (usbfs), that logic seems to be correct.
> >
> > Unless something is odd with creating a directory in the root of the fs.
> > Does the subdirectory you have created have the proper number of links?
>
> Yes, everything below the debug directory itself seems to be ok.
>
> > > Btw.: my find version: "GNU find version 4.2.20".
> > Hm, newer versions of find don't complain about this?
>
> The latest version I could find at http://ftp.gnu.org/pub/gnu/findutils/
> is 4.2.27 which still complains. No, idea from where you got the 4.2.30 :)

I'm running 4.3.0, not 4.2.30. I don't know where it came from either,
gentoo's unstable tree has it, and caused me to download it from
somewhere when I built it :)

thanks,

greg k-h

2006-01-27 17:43:36

by Vincent Hanquez

[permalink] [raw]
Subject: Re: [BUG] debugfs: hard link count wrong

On Thu, Jan 26, 2006 at 11:17:49PM -0800, Greg KH wrote:
> I'm running 4.3.0, not 4.2.30. I don't know where it came from either,
> gentoo's unstable tree has it, and caused me to download it from
> somewhere when I built it :)

looks like all fs that use simple_fill_super got a root inode with
i_nlink=1 at the start of day.

I've compared with shmem, the nlink is incremented to 2 by a call to
shmem_get_inode, when filling_super.

I've test the following patch with debugfs and securityfs, and its
seems to cure the problem.

------

Fix incorrect nlink of root inode for filesystems that use simple_fill_super

Signed-off-by: Vincent Hanquez <[email protected]>

diff -Naur a/fs/libfs.c a/fs/libfs.c
--- a/fs/libfs.c 2006-01-03 03:21:10.000000000 +0000
+++ b/fs/libfs.c 2006-01-27 17:43:31.000000000 +0000
@@ -388,6 +388,7 @@
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
inode->i_op = &simple_dir_inode_operations;
inode->i_fop = &simple_dir_operations;
+ inode->i_nlink = 2;
root = d_alloc_root(inode);
if (!root) {
iput(inode);

2006-01-30 06:52:09

by Heiko Carstens

[permalink] [raw]
Subject: Re: [BUG] debugfs: hard link count wrong

> looks like all fs that use simple_fill_super got a root inode with
> i_nlink=1 at the start of day.
>
> I've compared with shmem, the nlink is incremented to 2 by a call to
> shmem_get_inode, when filling_super.
>
> I've test the following patch with debugfs and securityfs, and its
> seems to cure the problem.
>
> ------
>
> Fix incorrect nlink of root inode for filesystems that use simple_fill_super
>
> Signed-off-by: Vincent Hanquez <[email protected]>
>
> diff -Naur a/fs/libfs.c a/fs/libfs.c
> --- a/fs/libfs.c 2006-01-03 03:21:10.000000000 +0000
> +++ b/fs/libfs.c 2006-01-27 17:43:31.000000000 +0000
> @@ -388,6 +388,7 @@
> inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
> inode->i_op = &simple_dir_inode_operations;
> inode->i_fop = &simple_dir_operations;
> + inode->i_nlink = 2;
> root = d_alloc_root(inode);
> if (!root) {
> iput(inode);
>
> -

Works fine for me. Is the patch ok, Greg?

Thanks,
Heiko

2006-02-01 12:08:51

by Heiko Carstens

[permalink] [raw]
Subject: Re: [BUG] debugfs: hard link count wrong

> looks like all fs that use simple_fill_super got a root inode with
> i_nlink=1 at the start of day.
>
> I've compared with shmem, the nlink is incremented to 2 by a call to
> shmem_get_inode, when filling_super.
>
> I've test the following patch with debugfs and securityfs, and its
> seems to cure the problem.
>
> ------
>
> Fix incorrect nlink of root inode for filesystems that use simple_fill_super
>
> Signed-off-by: Vincent Hanquez <[email protected]>
>
> diff -Naur a/fs/libfs.c a/fs/libfs.c
> --- a/fs/libfs.c 2006-01-03 03:21:10.000000000 +0000
> +++ b/fs/libfs.c 2006-01-27 17:43:31.000000000 +0000
> @@ -388,6 +388,7 @@
> inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
> inode->i_op = &simple_dir_inode_operations;
> inode->i_fop = &simple_dir_operations;
> + inode->i_nlink = 2;
> root = d_alloc_root(inode);
> if (!root) {
> iput(inode);
>
> -

Sorry to annoy you, but does this patch look ok? Who is actually the
maintainer of libfs?
Thought it would be good to have this fixed...
Thread started here:
http://marc.theaimsgroup.com/?l=linux-kernel&m=113828486029233&w=2

Thanks,
Heiko