Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 23 Jan 2000 17:30:44 -0800 (PST)
From:      krentel@dreamscape.com
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   bin/16320: fstat -f confuses some partitions
Message-ID:  <20000124013044.9D06C14E03@hub.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         16320
>Category:       bin
>Synopsis:       fstat -f confuses some partitions
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun Jan 23 17:40:00 PST 2000
>Closed-Date:
>Last-Modified:
>Originator:     Mark W. Krentel
>Release:        3.4-Release
>Organization:
none
>Environment:
FreeBSD 3.4-RELEASE #0: Tue Jan 11 15:38:38 EST 2000
>Description:
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.

>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.

>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 
--- fstat.c.orig        Sun Aug 29 11:28:06 1999
+++ fstat.c     Sat Jan 22 16:10:12 2000
@@ -441,7 +441,7 @@
                return;
        }
        if (nflg)
-               (void)printf(" %2d,%-2d", major(fst.fsid), minor(fst.fsid));
+               (void)printf(" %2d,%-2d", major(fst.fsid), minor(fst.fsid & 0xffff));
        else
                (void)printf(" %-8s", getmnton(vn.v_mount));
        if (nflg)
@@ -487,7 +487,7 @@
                    (void *)VTOI(vp), Pid);
                return 0;
        }
-       fsp->fsid = inode.i_dev & 0xffff;
+       fsp->fsid = inode.i_dev;
        fsp->fileid = (long)inode.i_number;
        fsp->mode = (mode_t)inode.i_mode;
        fsp->size = (u_long)inode.i_size;
@@ -765,7 +765,7 @@
        devs = cur;
 
        cur->ino = statbuf.st_ino;
-       cur->fsid = statbuf.st_dev & 0xffff;
+       cur->fsid = statbuf.st_dev;
        cur->name = filename;
        return(1);
 }


>Release-Note:
>Audit-Trail:
>Unformatted:


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20000124013044.9D06C14E03>