xfs-masters
[Top] [All Lists]

[xfs-masters] [Bug 432] New: dm_get_dirattrs cannot process directories

To: xfs-master@xxxxxxxxxxx
Subject: [xfs-masters] [Bug 432] New: dm_get_dirattrs cannot process directories with filenames > 165 characters
From: bugzilla-daemon@xxxxxxxxxxx
Date: Tue, 13 Dec 2005 04:41:21 -0800
Reply-to: xfs-masters@xxxxxxxxxxx
Sender: xfs-masters-bounce@xxxxxxxxxxx
http://oss.sgi.com/bugzilla/show_bug.cgi?id=432

           Summary: dm_get_dirattrs cannot process directories with
                    filenames > 165 characters
           Product: Linux XFS
           Version: Current
          Platform: PC
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: dmapi
        AssignedTo: xfs-master@xxxxxxxxxxx
        ReportedBy: c.pascoe@xxxxxxxxxxxxxx


A filename longer than 165 characters causes dm_get_dirattrs to terminate 
early (returns 0) when it hits it.  This is because in 
xfs_dm_get_dirattrs_rvp, direntbufsz is always initialised to 186 bytes,
which only leaves enough space for a 165 character filename.  When we hit
a file with a longer name, we return "done" because xfs_get_dirents
returns that it read none (same as when it hits end of directory).

The entire calculation and rationale of the direntbufsiz seems a little
strange, and also, the comment doesn't match the code (it uses NBPP
instead of bufsiz in the calculation).  Presumably the use of NBPP is to
stop users from allocating a huge hunk of kernel memory - though then down
a few lines we allocate all the memory they asked for anyway.

I'm also not sure why the DM_STAT_ALIGN values are used on the direntbufsz
entries, I can't see where the dirent code cares about these.  

Without introducing more return possibilities from xfs_get_dirents(), we
must always have enough space for at least one full-sized filename, so
using

   direntbufsz = sizeof(xfs_dirent_t) + MAXNAMLEN + (DM_STAT_ALIGN-1);
   direntbufsz &= ~(DM_STAT_ALIGN-1);

makes things work, but it isn't the "minimum that is guaranteed to fit" (I'm 
not sure there actually is a way to make xfs_get_dirents only get the
minimum number of entries "guaranteed to fit", as you don't know the size of 
each filename until you have gotten them), nor is it particularly efficient as 
you potentially only get one dirent returned to the user per ioctl.

It may also be worthwhile making the check a few lines above:

        if (buflen < DM_STAT_SIZE(dm_stat_t, MAXNAMLEN)) {

to suggest to the user that they should provide a buffer all the time that is 
guaranteed big enough for one file.

Example of the (mis)behaviour is below:

xchrisp@spruce:/usr/src/xfs-cmds-20050922/xfstests/dmapi/src/suite1/cmd$ dmesg 
| fgrep SGI-XFS
[17179691.900000] SGI-XFS CVS-2005-09-20_05:00_UTC with ACLs, security
attributes, large block numbers, dmapi support, no debug enabled

Using the code from the test suites, you can see 165 characters is fine,
but 166 is not.

xchrisp@spruce:/mnt/afile/TST$ :> `perl -e 'print "A"x165'`
xchrisp@spruce:/mnt/afile/TST$ sudo
/usr/src/xfs-cmds-20050922/xfstests/dmapi/src/suite1/cmd/get_dirattrs -b 
8192 /mnt/afile/TST/
ret = 1, rlenp is 384, loc is 6
handle 772d21865c61ea6e0e000000000000009300040000000000
name .
0x700|40093|S_IFDIR|0755|2|1003|666|0x0|4096|Oct  2 23:41:14 2005|Oct  2 
23:41:21 2005|Oct  2 23:41:21 2005|65536|8|0|(HASATTR)|0|1|0|(none)|23|0|0|Oct  
2 23:41:21 2005|0
handle 772d21865c61ea6e0e000000000000008000000000000000
name ..
0x700|80|S_IFDIR|01777|39|0|0|0x0|4096|Oct  2 23:37:33 2005|Oct  2 23:35:46 
2005|Oct  2 23:35:46 2005|65536|8|0|(none)|0|1|0|(none)|23|0|0|Oct  2 23:35:46 
2005|0
ret = 0, rlenp is 352, loc is 512
handle 772d21865c61ea6e0e000000030000009400040000000000
name
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAA
0x700|40094|S_IFREG|0644|1|1003|666|0x0|0|Oct  2 23:41:21 2005|Oct  2 23:41:21 
2005|Oct  2 23:41:21 2005|65536|8|3|(HASATTR)|0|0|1|(none)|23|0|0|Oct  2 
23:41:21 2005|0
xchrisp@spruce:/mnt/afile/TST$ rm
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAA

-- now create 166 byte filename

xchrisp@spruce:/mnt/afile/TST$ :> `perl -e 'print "B"x166'`
xchrisp@spruce:/mnt/afile/TST$ ls -la
total 8
drwxr-xr-x   2 xchrisp sysadm 4096 Oct  2 23:44 .
drwxrwxrwt  39 root    root   4096 Oct  2 23:35 ..
-rw-r--r--   1 xchrisp sysadm    0 Oct  2 23:44
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBB
xchrisp@spruce:/mnt/afile/TST$ sudo
/usr/src/xfs-cmds-20050922/xfstests/dmapi/src/suite1/cmd/get_dirattrs -b
8192 /mnt/afile/TST/
ret = 0, rlenp is 384, loc is 6
handle 772d21865c61ea6e0e000000000000009300040000000000
name .
0x700|40093|S_IFDIR|0755|2|1003|666|0x0|4096|Oct  2 23:44:18 2005|Oct  2 
23:44:41 2005|Oct  2 23:44:41 2005|65536|8|0|(HASATTR)|0|1|0|(none)|23|0|0|Oct  
2 23:44:41 2005|0
handle 772d21865c61ea6e0e000000000000008000000000000000
name ..
0x700|80|S_IFDIR|01777|39|0|0|0x0|4096|Oct  2 23:37:33 2005|Oct  2 23:35:46 
2005|Oct  2 23:35:46 2005|65536|8|0|(none)|0|1|0|(none)|23|0|0|Oct  2 23:35:46 
2005|0

-- 
Configure bugmail: http://oss.sgi.com/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.


<Prev in Thread] Current Thread [Next in Thread>
  • [xfs-masters] [Bug 432] New: dm_get_dirattrs cannot process directories with filenames > 165 characters, bugzilla-daemon <=