Using fstatfs on a ZFS disk

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

Using fstatfs on a ZFS disk

Willem Jan Withagen-2
Hi,

I'm trying to find the values of the returned f_type for ZFS
in the fstatfs call when a file is on ZFS....

But I have not yet found the definitions of the ENUMS that
would fill that value... Let alone the value for ZFS.

      struct statfs {
      uint32_t f_version;             /* structure version number */
      uint32_t f_type;                /* type of filesystem */
      uint64_t f_flags;               /* copy of mount exported flags */
      ......
      }

Any hints where to look would be welcomed.

Thanx,
--WjW
_______________________________________________
[hidden email] mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "[hidden email]"
Reply | Threaded
Open this post in threaded view
|

Re: Using fstatfs on a ZFS disk

Bob Bishop
Hi,

> On 19 Feb 2018, at 14:48, Willem Jan Withagen <[hidden email]> wrote:
>
> Hi,
>
> I'm trying to find the values of the returned f_type for ZFS
> in the fstatfs call when a file is on ZFS....
>
> But I have not yet found the definitions of the ENUMS that
> would fill that value... Let alone the value for ZFS.

I chased this particular wild goose myself recently. It’s FS_... in  /usr/include/sys/disklabel,h that you want.

>     struct statfs {
>     uint32_t f_version;             /* structure version number */
>     uint32_t f_type;                /* type of filesystem */
>     uint64_t f_flags;               /* copy of mount exported flags */
>     ......
>     }
>
> Any hints where to look would be welcomed.
>
> Thanx,
> --WjW
> _______________________________________________
> [hidden email] mailing list
> https://lists.freebsd.org/mailman/listinfo/freebsd-hackers
> To unsubscribe, send any mail to "[hidden email]"
>

--
Bob Bishop
[hidden email]




_______________________________________________
[hidden email] mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "[hidden email]"
Reply | Threaded
Open this post in threaded view
|

Re: Using fstatfs on a ZFS disk

Willem Jan Withagen-2
On 19-2-2018 16:00, Bob Bishop wrote:

> Hi,
>
>> On 19 Feb 2018, at 14:48, Willem Jan Withagen <[hidden email]> wrote:
>>
>> Hi,
>>
>> I'm trying to find the values of the returned f_type for ZFS
>> in the fstatfs call when a file is on ZFS....
>>
>> But I have not yet found the definitions of the ENUMS that
>> would fill that value... Let alone the value for ZFS.
>
> I chased this particular wild goose myself recently. It’s FS_... in  /usr/include/sys/disklabel,h that you want.

Hi Bob,

I grepped on MAGIC and FS, but the combo did not deliver anything
useful. So this is already more that I found.
I did get:
/usr/include/ufs/ffs/fs.h:#define       FS_UFS1_MAGIC   0x011954
/* UFS1 fast filesystem magic number */
/usr/include/ufs/ffs/fs.h:#define       FS_UFS2_MAGIC   0x19540119
/* UFS2 fast filesystem magic number */
/usr/include/ufs/ffs/fs.h:#define       FS_BAD_MAGIC    0x19960408
/* UFS incomplete newfs magic number */

So I was looking for something like: FS_ZFS_MAGIC

disklabel.h contains:
#ifdef  FSTYPENAMES
static const char *fstypenames[] = {

And further search:
/usr/include/sys/disk/bsd.h:#define     FS_ZFS  27    /* Sun's ZFS */

Running:
#include "stdio.h"

#include <sys/param.h>
#include <sys/mount.h>

int main() {
         struct statfs fstr;
         char * str;

         str = "/tmp";
         statfs(str, &fstr);
         printf("%s, ftype: 0x%x.\n", str, fstr.f_type);
}
results in:
        /tmp, ftype: 0xde.

Now 0xde != 27, so the question is, where is this 0xde specified.
And more important is this f_type constant over all FreeBSD ZFS filesystems?


--WjW

>
>>      struct statfs {
>>      uint32_t f_version;             /* structure version number */
>>      uint32_t f_type;                /* type of filesystem */
>>      uint64_t f_flags;               /* copy of mount exported flags */
>>      ......
>>      }
>>
>> Any hints where to look would be welcomed.
>>
>> Thanx,
>> --WjW
>> _______________________________________________
>> [hidden email] mailing list
>> https://lists.freebsd.org/mailman/listinfo/freebsd-hackers
>> To unsubscribe, send any mail to "[hidden email]"
>>
>
> --
> Bob Bishop
> [hidden email]
>
>
>
>

_______________________________________________
[hidden email] mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "[hidden email]"
Reply | Threaded
Open this post in threaded view
|

Re: Using fstatfs on a ZFS disk

Bob Bishop
Hi,

> On 19 Feb 2018, at 15:50, Willem Jan Withagen <[hidden email]> wrote:
>
> On 19-2-2018 16:00, Bob Bishop wrote:
>> Hi,
>>> On 19 Feb 2018, at 14:48, Willem Jan Withagen <[hidden email]> wrote:
>>>
>>> Hi,
>>>
>>> I'm trying to find the values of the returned f_type for ZFS
>>> in the fstatfs call when a file is on ZFS....
>>>
>>> But I have not yet found the definitions of the ENUMS that
>>> would fill that value... Let alone the value for ZFS.
>> I chased this particular wild goose myself recently. It’s FS_... in  /usr/include/sys/disklabel,h that you want.
>
> Hi Bob,
>
> I grepped on MAGIC and FS, but the combo did not deliver anything useful. So this is already more that I found.
> I did get:
> /usr/include/ufs/ffs/fs.h:#define       FS_UFS1_MAGIC   0x011954 /* UFS1 fast filesystem magic number */
> /usr/include/ufs/ffs/fs.h:#define       FS_UFS2_MAGIC   0x19540119 /* UFS2 fast filesystem magic number */
> /usr/include/ufs/ffs/fs.h:#define       FS_BAD_MAGIC    0x19960408 /* UFS incomplete newfs magic number */

Those I believe are magic numbers for UFS superblocks...

> So I was looking for something like: FS_ZFS_MAGIC

... so you won’t find that.

> disklabel.h contains:
> #ifdef  FSTYPENAMES
> static const char *fstypenames[] = {
>
> And further search:
> /usr/include/sys/disk/bsd.h:#define     FS_ZFS  27    /* Sun's ZFS */
>
> Running:
> #include "stdio.h"
>
> #include <sys/param.h>
> #include <sys/mount.h>
>
> int main() {
>        struct statfs fstr;
>        char * str;
>
>        str = "/tmp";
>        statfs(str, &fstr);
>        printf("%s, ftype: 0x%x.\n", str, fstr.f_type);
> }
> results in:
> /tmp, ftype: 0xde.
>
> Now 0xde != 27, so the question is, where is this 0xde specified.
> And more important is this f_type constant over all FreeBSD ZFS filesystems?

You got me. And a quick look at sys/kern/vfs_syscalls.c doesn’t help except to imply that the type is set when the filesystem is mounted. I have no idea where 0xde comes from.

> --WjW
>
>>>     struct statfs {
>>>     uint32_t f_version;             /* structure version number */
>>>     uint32_t f_type;                /* type of filesystem */
>>>     uint64_t f_flags;               /* copy of mount exported flags */
>>>     ......
>>>     }
>>>
>>> Any hints where to look would be welcomed.
>>>
>>> Thanx,
>>> --WjW
>>> _______________________________________________
>>> [hidden email] mailing list
>>> https://lists.freebsd.org/mailman/listinfo/freebsd-hackers
>>> To unsubscribe, send any mail to "[hidden email]"
>>>
>> --
>> Bob Bishop
>> [hidden email]
>


--
Bob Bishop       t: +44 (0)118 940 1243
[hidden email]     m: +44 (0)783 626 4518





_______________________________________________
[hidden email] mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "[hidden email]"
Reply | Threaded
Open this post in threaded view
|

Re: Using fstatfs on a ZFS disk

Rodney W. Grimes-4
> Hi,
>
> > On 19 Feb 2018, at 15:50, Willem Jan Withagen <[hidden email]> wrote:
> >
> > On 19-2-2018 16:00, Bob Bishop wrote:
> >> Hi,
> >>> On 19 Feb 2018, at 14:48, Willem Jan Withagen <[hidden email]> wrote:
> >>>
> >>> Hi,
> >>>
> >>> I'm trying to find the values of the returned f_type for ZFS
> >>> in the fstatfs call when a file is on ZFS....
> >>>
> >>> But I have not yet found the definitions of the ENUMS that
> >>> would fill that value... Let alone the value for ZFS.
> >> I chased this particular wild goose myself recently. It?s FS_... in  /usr/include/sys/disklabel,h that you want.
> >
> > Hi Bob,
> >
> > I grepped on MAGIC and FS, but the combo did not deliver anything useful. So this is already more that I found.
> > I did get:
> > /usr/include/ufs/ffs/fs.h:#define       FS_UFS1_MAGIC   0x011954 /* UFS1 fast filesystem magic number */
> > /usr/include/ufs/ffs/fs.h:#define       FS_UFS2_MAGIC   0x19540119 /* UFS2 fast filesystem magic number */
> > /usr/include/ufs/ffs/fs.h:#define       FS_BAD_MAGIC    0x19960408 /* UFS incomplete newfs magic number */
>
> Those I believe are magic numbers for UFS superblocks...
>
> > So I was looking for something like: FS_ZFS_MAGIC
>
> ... so you won?t find that.
>
> > disklabel.h contains:
> > #ifdef  FSTYPENAMES
> > static const char *fstypenames[] = {
> >
> > And further search:
> > /usr/include/sys/disk/bsd.h:#define     FS_ZFS  27    /* Sun's ZFS */
> >
> > Running:
> > #include "stdio.h"
> >
> > #include <sys/param.h>
> > #include <sys/mount.h>
> >
> > int main() {
> >        struct statfs fstr;
> >        char * str;
> >
> >        str = "/tmp";
> >        statfs(str, &fstr);
> >        printf("%s, ftype: 0x%x.\n", str, fstr.f_type);
> > }
> > results in:
> > /tmp, ftype: 0xde.
> >
> > Now 0xde != 27, so the question is, where is this 0xde specified.
> > And more important is this f_type constant over all FreeBSD ZFS filesystems?
>
> You got me. And a quick look at sys/kern/vfs_syscalls.c doesn?t help except to imply that the type is set when the filesystem is mounted. I have no idea where 0xde comes from.

Could that 0xde be the start of 0xdeadcode?

0xde is 222 decimal, that does not ring a bell for me either.


> > --WjW
> >
> >>>     struct statfs {
> >>>     uint32_t f_version;             /* structure version number */
> >>>     uint32_t f_type;                /* type of filesystem */
> >>>     uint64_t f_flags;               /* copy of mount exported flags */
> >>>     ......
> >>>     }
> >>>
> >>> Any hints where to look would be welcomed.
> >>>
> >>> Thanx,
> >>> --WjW
> >> --
> >> Bob Bishop
> >> [hidden email]
> --
> Bob Bishop       t: +44 (0)118 940 1243
> [hidden email]     m: +44 (0)783 626 4518

--
Rod Grimes                                                 [hidden email]
_______________________________________________
[hidden email] mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "[hidden email]"
Reply | Threaded
Open this post in threaded view
|

Re: Using fstatfs on a ZFS disk

Willem Jan Withagen-2
On 19/02/2018 19:33, Rodney W. Grimes wrote:

>> Hi,
>>
>>> On 19 Feb 2018, at 15:50, Willem Jan Withagen <[hidden email]> wrote:
>>>
>>> On 19-2-2018 16:00, Bob Bishop wrote:
>>>> Hi,
>>>>> On 19 Feb 2018, at 14:48, Willem Jan Withagen <[hidden email]> wrote:
>>>>>
>>>>> Hi,
>>>>>
>>>>> I'm trying to find the values of the returned f_type for ZFS
>>>>> in the fstatfs call when a file is on ZFS....
>>>>>
>>>>> But I have not yet found the definitions of the ENUMS that
>>>>> would fill that value... Let alone the value for ZFS.
>>>> I chased this particular wild goose myself recently. It?s FS_... in  /usr/include/sys/disklabel,h that you want.
>>>
>>> Hi Bob,
>>>
>>> I grepped on MAGIC and FS, but the combo did not deliver anything useful. So this is already more that I found.
>>> I did get:
>>> /usr/include/ufs/ffs/fs.h:#define       FS_UFS1_MAGIC   0x011954 /* UFS1 fast filesystem magic number */
>>> /usr/include/ufs/ffs/fs.h:#define       FS_UFS2_MAGIC   0x19540119 /* UFS2 fast filesystem magic number */
>>> /usr/include/ufs/ffs/fs.h:#define       FS_BAD_MAGIC    0x19960408 /* UFS incomplete newfs magic number */
>>
>> Those I believe are magic numbers for UFS superblocks...
>>
>>> So I was looking for something like: FS_ZFS_MAGIC
>>
>> ... so you won?t find that.
>>
>>> disklabel.h contains:
>>> #ifdef  FSTYPENAMES
>>> static const char *fstypenames[] = {
>>>
>>> And further search:
>>> /usr/include/sys/disk/bsd.h:#define     FS_ZFS  27    /* Sun's ZFS */
>>>
>>> Running:
>>> #include "stdio.h"
>>>
>>> #include <sys/param.h>
>>> #include <sys/mount.h>
>>>
>>> int main() {
>>>         struct statfs fstr;
>>>         char * str;
>>>
>>>         str = "/tmp";
>>>         statfs(str, &fstr);
>>>         printf("%s, ftype: 0x%x.\n", str, fstr.f_type);
>>> }
>>> results in:
>>> /tmp, ftype: 0xde.
>>>
>>> Now 0xde != 27, so the question is, where is this 0xde specified.
>>> And more important is this f_type constant over all FreeBSD ZFS filesystems?
>>
>> You got me. And a quick look at sys/kern/vfs_syscalls.c doesn?t help except to imply that the type is set when the filesystem is mounted. I have no idea where 0xde comes from.
>
> Could that 0xde be the start of 0xdeadcode?
>
> 0xde is 222 decimal, that does not ring a bell for me either.

Searching on 0xde did deliver indeed plenty 0xdeadc0de and sisters.
the resulting size is 32bit, so if it is a leftover of 0xdeadcode, it is
due to a not-32bit aligned access, since the 3 upper bytes are 0.

Only way to find this out is dig thru the code. :) But I'm no hero at that.

But there is atleast not a particular FS_ZFS_MAGIC!!
And there is no obvious definition what is returned in f_type??

--WjW

>>>>>      struct statfs {
>>>>>      uint32_t f_version;             /* structure version number */
>>>>>      uint32_t f_type;                /* type of filesystem */
>>>>>      uint64_t f_flags;               /* copy of mount exported flags */
>>>>>      ......
>>>>>      }
>>>>>
>>>>> Any hints where to look would be welcomed.
>>>>>
>>>>> Thanx,
>>>>> --WjW
>>>> --
>>>> Bob Bishop
>>>> [hidden email]
>> --
>> Bob Bishop       t: +44 (0)118 940 1243
>> [hidden email]     m: +44 (0)783 626 4518
>

_______________________________________________
[hidden email] mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "[hidden email]"
Reply | Threaded
Open this post in threaded view
|

Re: Using fstatfs on a ZFS disk

Andriy Gapon
In reply to this post by Rodney W. Grimes-4
On 19/02/2018 20:33, Rodney W. Grimes wrote:
>> Hi,
>>
>>> On 19 Feb 2018, at 15:50, Willem Jan Withagen <[hidden email]> wrote:

>>> Now 0xde != 27, so the question is, where is this 0xde specified.
>>> And more important is this f_type constant over all FreeBSD ZFS filesystems?
>>
>> You got me. And a quick look at sys/kern/vfs_syscalls.c doesn?t help except to imply that the type is set when the filesystem is mounted. I have no idea where 0xde comes from.
>
> Could that 0xde be the start of 0xdeadcode?
>
> 0xde is 222 decimal, that does not ring a bell for me either.

This is simpler, I think.
It is a hash value (calculated using a specific algorithm) of a filesystem type
name.  See vfs_register().
There are no magic predefined constants for the types.

BTW, lsvfs(1) and its source code could be of interest to the original poster.
E.g., getvfsbyname(3).

--
Andriy Gapon
_______________________________________________
[hidden email] mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "[hidden email]"
Reply | Threaded
Open this post in threaded view
|

Re: Using fstatfs on a ZFS disk

Willem Jan Withagen-2
In reply to this post by Rodney W. Grimes-4
On 19-2-2018 19:33, Rodney W. Grimes wrote:

>> Hi,
>>
>>> On 19 Feb 2018, at 15:50, Willem Jan Withagen <[hidden email]> wrote:
>>>
>>> On 19-2-2018 16:00, Bob Bishop wrote:
>>>> Hi,
>>>>> On 19 Feb 2018, at 14:48, Willem Jan Withagen <[hidden email]> wrote:
>>>>>
>>>>> Hi,
>>>>>
>>>>> I'm trying to find the values of the returned f_type for ZFS
>>>>> in the fstatfs call when a file is on ZFS....
>>>>>
>>>>> But I have not yet found the definitions of the ENUMS that
>>>>> would fill that value... Let alone the value for ZFS.
>>>> I chased this particular wild goose myself recently. It?s FS_... in  /usr/include/sys/disklabel,h that you want.
>>>
>>> Hi Bob,
>>>
>>> I grepped on MAGIC and FS, but the combo did not deliver anything useful. So this is already more that I found.
>>> I did get:
>>> /usr/include/ufs/ffs/fs.h:#define       FS_UFS1_MAGIC   0x011954 /* UFS1 fast filesystem magic number */
>>> /usr/include/ufs/ffs/fs.h:#define       FS_UFS2_MAGIC   0x19540119 /* UFS2 fast filesystem magic number */
>>> /usr/include/ufs/ffs/fs.h:#define       FS_BAD_MAGIC    0x19960408 /* UFS incomplete newfs magic number */
>>
>> Those I believe are magic numbers for UFS superblocks...
>>
>>> So I was looking for something like: FS_ZFS_MAGIC
>>
>> ... so you won?t find that.
>>
>>> disklabel.h contains:
>>> #ifdef  FSTYPENAMES
>>> static const char *fstypenames[] = {
>>>
>>> And further search:
>>> /usr/include/sys/disk/bsd.h:#define     FS_ZFS  27    /* Sun's ZFS */
>>>
>>> Running:
>>> #include "stdio.h"
>>>
>>> #include <sys/param.h>
>>> #include <sys/mount.h>
>>>
>>> int main() {
>>>         struct statfs fstr;
>>>         char * str;
>>>
>>>         str = "/tmp";
>>>         statfs(str, &fstr);
>>>         printf("%s, ftype: 0x%x.\n", str, fstr.f_type);
>>> }
>>> results in:
>>> /tmp, ftype: 0xde.
>>>
>>> Now 0xde != 27, so the question is, where is this 0xde specified.
>>> And more important is this f_type constant over all FreeBSD ZFS filesystems?
>>
>> You got me. And a quick look at sys/kern/vfs_syscalls.c doesn?t help except to imply that the type is set when the filesystem is mounted. I have no idea where 0xde comes from.
>
> Could that 0xde be the start of 0xdeadcode?
>
> 0xde is 222 decimal, that does not ring a bell for me either.

Well the VSTAT node gets setup during vfs_mount_alloc() which copies
data from:
/*
  * Filesystem configuration information. One of these exists for each
  * type of filesystem supported by the kernel. These are searched at
  * mount time to identify the requested filesystem.
  *
  * XXX: Never change the first two arguments!
  */
struct vfsconf {
   u_int   vfc_version;            /* ABI version number */
   char    vfc_name[MFSNAMELEN];   /* filesystem type name */
   struct  vfsops *vfc_vfsops;     /* filesystem operations vector */
   int     vfc_typenum;            /* historic filesystem type number */
   int     vfc_refcount;           /* number mounted of this type */
   int     vfc_flags;              /* permanent flags */
   struct  vfsoptdecl *vfc_opts;   /* mount options */
   TAILQ_ENTRY(vfsconf) vfc_list;  /* list of vfscons */
};

And the "historic filesystem type number" is a worrying comment.

As it turns out the type is calculated/hashed in vfs_init:
====
     if (vfs_typenumhash != 0) {
        /*
         * Calculate a hash on vfc_name to use for vfc_typenum. Unless
         * all of 1<->255 are assigned, it is limited to 8bits since
         * that is what ZFS uses from vfc_typenum and is also the
         * preferred range for vfs_getnewfsid().
         */
        hashval = fnv_32_str(vfc->vfc_name, FNV1_32_INIT);
        hashval &= 0xff;
        secondpass = 0;
        do {
             /* Look for and fix any collision. */
             TAILQ_FOREACH(tvfc, &vfsconf, vfc_list) {
                 if (hashval == tvfc->vfc_typenum) {
                     if (hashval == 255 && secondpass == 0) {
                          hashval = 1;
                          secondpass = 1;
                      } else
                          hashval++;
                      break;
                  }
             }
        } while (tvfc != NULL);
        vfc->vfc_typenum = hashval;
        if (vfc->vfc_typenum >= maxvfsconf)
            maxvfsconf = vfc->vfc_typenum + 1;

So the f_type is sort of stable over time, unless een new type creates a
collision and things start moving.

Made a small test program:
/tmp, ftype: 0xde, name: zfs.
/home/wjw, ftype: 0x3a, name: nfs.
/home/wjw/.tcshrc, ftype: 0x3a, name: nfs.
/dev/random, ftype: 0x71, name: devfs.

So I guess I'm going to '#define FS_ZFS_TYPE 0xde'
--WjW
_______________________________________________
[hidden email] mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "[hidden email]"
Reply | Threaded
Open this post in threaded view
|

Re: Using fstatfs on a ZFS disk

Willem Jan Withagen-2
In reply to this post by Andriy Gapon
On 19-2-2018 22:20, Andriy Gapon wrote:

> On 19/02/2018 20:33, Rodney W. Grimes wrote:
>>> Hi,
>>>
>>>> On 19 Feb 2018, at 15:50, Willem Jan Withagen <[hidden email]> wrote:
>
>>>> Now 0xde != 27, so the question is, where is this 0xde specified.
>>>> And more important is this f_type constant over all FreeBSD ZFS filesystems?
>>>
>>> You got me. And a quick look at sys/kern/vfs_syscalls.c doesn?t help except to imply that the type is set when the filesystem is mounted. I have no idea where 0xde comes from.
>>
>> Could that 0xde be the start of 0xdeadcode?
>>
>> 0xde is 222 decimal, that does not ring a bell for me either.
>
> This is simpler, I think.
> It is a hash value (calculated using a specific algorithm) of a filesystem type
> name.  See vfs_register().

Right in vfs_init.c

> There are no magic predefined constants for the types.

It is a bit of work doing the hashes, but there could very well be
pre-calculated FS_<fs>_TYPE defines.

See my other post.

> BTW, lsvfs(1) and its source code could be of interest to the original poster.
> E.g., getvfsbyname(3).

lsvfs output could even be used to generate part of the ENUM list.

--WjW


_______________________________________________
[hidden email] mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "[hidden email]"