From: Waldemar Kozaczuk <
jwkoz...@gmail.com>
Committer: Waldemar Kozaczuk <
jwkoz...@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 <
jwkoz...@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");