Bug 16320

Summary: fstat -f confuses some partitions
Product: Base System Reporter: krentel <krentel>
Component: binAssignee: dwmalone
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: Unspecified   
Hardware: Any   
OS: Any   
Attachments:
Description Flags
file.diff none

Description krentel 2000-01-24 01:40:00 UTC
The -f flag for /usr/bin/fstat is supposed to "Restrict examination to
files open in the same filesystems as the named file arguments."
But some partitions are considered equivalent, when they are not.

The problem happens whenever there are two partitions with the same
letter on different slices of the same disk.  For example, I put /home
on a separate slice, so /usr and /home are both the "f" partition of
two slices:

  # Device       Mountpoint    FStype   Options     Dump    Pass
  /dev/da0s2f    /usr          ufs      rw          2       2
  /dev/da0s3f    /home         ufs      rw          2       2

  % ls -l /dev/da0*f
  brw-r-----  1 root  operator    4,   5 Dec 24 20:06 /dev/da0f
  brw-r-----  1 root  operator    4, 0x00030005 Jul  1  1999 /dev/da0s2f
  brw-r-----  1 root  operator    4, 0x00040005 Jul  1  1999 /dev/da0s3f

In fstat.c, in ufs_filestat, the program computes a unique identifier
for the file system (fsid) as:

     fsp->fsid = inode.i_dev & 0xffff;

The 0xffff mask erases the high-order bits of the device's minor number.
This makes fstat incorrectly think that da0s2f and da0s3f are the same
partition because they both have fsid == 0x0405.  So, when I ask for
just /home, I get both /home and /usr:

  % fstat -f /home 
  USER     CMD          PID   FD MOUNT      INUM MODE         SZ|DV R/W
  krentel  fstat      10702   wd /home    315401 drwxr-xr-x    2048  r
  krentel  fstat      10702 text /usr       7946 -r-xr-sr-x   10160  r
  ...

I noticed this in 3.4-Release, but from looking at the CVS repository,
it's clear that current has the same behavior.

Fix: I suggest the following patch.  It removes the 0xffff mask from fsid,
so fstat correctly distinguishes between da0s1f and da0s2f.  Instead,
it puts the mask on the printf statement, so fstat -n continues to
display da0s2f as device 4,5 instead of 4,0x00030005.

Or, maybe da0s2f really should print as 4,0x00030005, I don't know.
I've never been that clear on Freebsd's use of the high-order bits
in the minor number.

This patch is for 3.4-Release (rev 1.16.2.2 of fstat.c), but it's
basically the same for current.

% diff -u fstat.c.orig fstat.c 
How-To-Repeat: Create two partitions with the same letter on different slices of the 
same disk.  For example,

  /dev/da0s1f    /foo
  /dev/da0s2f    /bar

Then, "fstat -f /foo" includes files on both /foo and /bar.
Comment 1 Bruce Evans 2000-01-24 07:02:50 UTC
On Sun, 23 Jan 2000 krentel@dreamscape.com wrote:

> >Fix:
> I suggest the following patch.  It removes the 0xffff mask from fsid,
> so fstat correctly distinguishes between da0s1f and da0s2f.  Instead,
> it puts the mask on the printf statement, so fstat -n continues to
> display da0s2f as device 4,5 instead of 4,0x00030005.
> 
> Or, maybe da0s2f really should print as 4,0x00030005, I don't know.
> I've never been that clear on Freebsd's use of the high-order bits
> in the minor number.

fstat should print the full number, but this will mess up the formatting.
It uses %2d formatting, so it already messes up minor numbers larger than
99.

Bruce
Comment 2 krentel 2000-01-25 02:53:28 UTC
> fstat should print the full number, but this will mess up the formatting.
> It uses %2d formatting, so it already messes up minor numbers larger than
> 99.

Yeah, ls has a similar problem.  Short of inventing some new letters
and printing the numbers in base r256, I don't know what to suggest.

Do you agree with the rest of the patch?  I guess current is in code
slush now.  But 3.x is in a bit of a lull between releases, if you
feel inclined to commit something.

--Mark
Comment 3 dwmalone freebsd_committer freebsd_triage 2001-08-02 15:09:10 UTC
Responsible Changed
From-To: freebsd-bugs->dwmalone

I'm having a look at a related PR, so I'll take this one too.
Comment 4 dwmalone freebsd_committer freebsd_triage 2001-11-21 10:50:12 UTC
State Changed
From-To: open->closed

Fixed in -current and -stable. Thanks!
Comment 5 krentel 2001-11-24 05:43:24 UTC
Thanks for committing the patch.  But now I'm wondering what is the
proper format for printing the major/minor numbers with fstat -n.
Should it be decimal or hex.  fstat uses " %2d,%-2d", so it prints as:

   % ./fstat -n | head -3
   USER     CMD          PID   FD  DEV    INUM       MODE SZ|DV R/W
   krentel  bash       12338 root 13,196608      2      40755    512  r
   krentel  bash       12338   wd 13,262149 167325      40755    512  r

But ls uses "%3d, 0x%08x " for minor numbers < 0 or > 255 which is
longer but easier to understand.  Both mess up the format.

   % ls -l /dev/da0s2[ab]
   crw-r-----  2 root  operator   13, 0x00030000 Oct  6 21:47 /dev/da0s2a
   crw-r-----  2 root  operator   13, 0x00030001 Oct  6 21:47 /dev/da0s2b

So, I'm wondering if there's a consensus on this.

--Mark