From: Waldemar Kozaczuk <jwkozac...@gmail.com>
Committer: Waldemar Kozaczuk <jwkozac...@gmail.com>
Branch: master

zfs: avoid f_fsid sign extension when translating f_fsid to va_fsid

This would have been a cosmetic change except in future patches
we rely on full value of f_fsid field including higher 32 bits in order to
determine type of the file system.

Before this patch if lower 32 bits of f_fsid (stored as signed int)
represented negative number, it would lead to overwriting higher 32 bits
when translating to va_fsid in zfs_getattr() function.

For example if f_fsid was composed like this:

lower  32-bits: 0x9a16baf6
higher 32-bits: 0x06567a36

before this patch the resulting va_fsid would be translated as:
0xffffffff9a16baf6

where we lose the high 32 bits of f_fsid.

With this patch va_fsid would look like this:
0x06567a369a16baf6

This patch is loosely similar to the patch applied 3 years ago
to the original ZFS source tree in FreeBSD - 
https://github.com/freebsd/freebsd/commit/0a0bd3828b5387a70d59645d9aee559c60ca77a5

Signed-off-by: Waldemar Kozaczuk <jwkozac...@gmail.com>

---
diff --git a/bsd/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c 
b/bsd/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
--- a/bsd/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
+++ b/bsd/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
@@ -2041,6 +2041,7 @@ zfs_getattr(vnode_t *vp, vattr_t *vap)
        xoptattr_t *xoap = NULL;
        sa_bulk_attr_t bulk[4];
        int count = 0;
+       fsid_t *fsid;
 
        ZFS_ENTER(zfsvfs);
        ZFS_VERIFY_ZP(zp);
@@ -2068,8 +2069,8 @@ zfs_getattr(vnode_t *vp, vattr_t *vap)
 #ifdef sun
        vap->va_fsid = zp->z_zfsvfs->z_vfs->vfs_dev;
 #else
-       vap->va_fsid =  zp->z_zfsvfs->z_vfs->vfs_fsid.__val[0] |
-               ((dev_t) zp->z_zfsvfs->z_vfs->vfs_fsid.__val[1] << 32);
+       fsid = &zp->z_zfsvfs->z_vfs->vfs_fsid;
+       vap->va_fsid = ((uint32_t)fsid->__val[0]) | ((dev_t) 
((uint32_t)fsid->__val[1]) << 32);
 #endif
        vap->va_nodeid = zp->z_id;
        if ((vp->v_flags & VROOT) && zfs_show_ctldir(zp))
diff --git a/tests/tst-zfs-mount.cc b/tests/tst-zfs-mount.cc
--- a/tests/tst-zfs-mount.cc
+++ b/tests/tst-zfs-mount.cc
@@ -173,8 +173,8 @@ int main(int argc, char **argv)
 
     printf("file size = %lld\n", s.st_size);
 
-    report((((dev_t) st.f_fsid.__val[1] << 32) | st.f_fsid.__val[0]) == 
s.st_dev,
-           "st_dev must be equals to f_fsid");
+    dev_t f_fsid = ((uint32_t)st.f_fsid.__val[0]) | ((dev_t) 
((uint32_t)st.f_fsid.__val[1]) << 32);
+    report(f_fsid == s.st_dev, "st_dev must be equals to f_fsid");
 
     report(close(fd) == 0, "close fd");
 

-- 
You received this message because you are subscribed to the Google Groups "OSv 
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to osv-dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/osv-dev/00000000000057207605a44fdb93%40google.com.

Reply via email to