Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 17 Jun 2022 01:35:54 +0000
From:      bugzilla-noreply@freebsd.org
To:        bugs@FreeBSD.org
Subject:   [Bug 264723] the KERN_LOCKF sysctl returns kl_file_fsid that doesn't match st_dev from stat()
Message-ID:  <bug-264723-227@https.bugs.freebsd.org/bugzilla/>

next in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D264723

            Bug ID: 264723
           Summary: the KERN_LOCKF sysctl returns kl_file_fsid that
                    doesn't match st_dev from stat()
           Product: Base System
           Version: CURRENT
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Some People
          Priority: ---
         Component: kern
          Assignee: bugs@FreeBSD.org
          Reporter: damjan.jov@gmail.com

The new KERN_LOCKF sysctl (great work btw) returns struct kinfo_lockf, whose
kl_file_fsid matches neither the st_dev from stat(), nor the kf_file_fsid f=
rom
kinfo_getfiles() (even though stat() and kinfo_getfiles() match each other).
For example compare the FSID in "procstat advlock" for a locked file, with =
the
st_dev in "stat -s" output on it.

vop_stdstat() derives st_dev like this:
---snip---
        if (vap->va_fsid !=3D VNOVAL)
                sb->st_dev =3D vap->va_fsid;
        else
                sb->st_dev =3D vp->v_mount->mnt_stat.f_fsid.val[0];
---snip---


vn_fill_kinfo_vnode() derives kf_file_fsid the same way:
---snip---
        if (va.va_fsid !=3D VNOVAL)
                kif->kf_un.kf_file.kf_file_fsid =3D va.va_fsid;
        else
                kif->kf_un.kf_file.kf_file_fsid =3D
                    vp->v_mount->mnt_stat.f_fsid.val[0];
---snip---


But vfs_report_lockf() uses the entire mnt_stat.f_fsid, not just array elem=
ent
0, and never uses va.va_fsid:
---snip---
       fsidx =3D mp->mnt_stat.f_fsid;
       ...
                               memcpy(&klf->kl.kl_file_fsid, &fsidx,
                                   sizeof(fsidx));
---snip---


vfs_report_lockf() does call VOP_STAT(), which is (usually?) the vop_stdsta=
t()
function above, so it should be able to just copy its correctly populated
st_dev to kl_file_fsid. When I do that, as in the following patch, it seems=
 to
work, the FSID in "procstat advlock" matches the st_dev in "stat -s":


---snip---
diff --git a/sys/kern/kern_lockf.c b/sys/kern/kern_lockf.c
index cad208197e7..98e29b2c929 100644
--- a/sys/kern/kern_lockf.c
+++ b/sys/kern/kern_lockf.c
@@ -2479,7 +2479,6 @@ vfs_report_lockf(struct mount *mp, struct sbuf *sb)
        struct ucred *ucred;
        char *fullpath, *freepath;
        struct stat stt;
-       fsid_t fsidx;
        STAILQ_HEAD(, kinfo_lockf_linked) locks;
        int error, gerror;

@@ -2522,7 +2521,6 @@ vfs_report_lockf(struct mount *mp, struct sbuf *sb)

        gerror =3D 0;
        ucred =3D curthread->td_ucred;
-       fsidx =3D mp->mnt_stat.f_fsid;
        while ((klf =3D STAILQ_FIRST(&locks)) !=3D NULL) {
                STAILQ_REMOVE_HEAD(&locks, link);
                vp =3D klf->vp;
@@ -2532,8 +2530,7 @@ vfs_report_lockf(struct mount *mp, struct sbuf *sb)
                                error =3D VOP_STAT(vp, &stt, ucred, NOCRED);
                        VOP_UNLOCK(vp);
                        if (error =3D=3D 0) {
-                               memcpy(&klf->kl.kl_file_fsid, &fsidx,
-                                   sizeof(fsidx));
+                               klf->kl.kl_file_fsid =3D stt.st_dev;
                                klf->kl.kl_file_rdev =3D stt.st_rdev;
                                klf->kl.kl_file_fileid =3D stt.st_ino;
                                freepath =3D NULL;
---snip---

--=20
You are receiving this mail because:
You are the assignee for the bug.=



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