The branch main has been updated by mjg:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=a15f787adb4429b83fa911dcb60f69121aaee1ba

commit a15f787adb4429b83fa911dcb60f69121aaee1ba
Author:     Mateusz Guzik <m...@freebsd.org>
AuthorDate: 2021-02-15 22:08:40 +0000
Commit:     Mateusz Guzik <m...@freebsd.org>
CommitDate: 2021-02-21 00:43:05 +0000

    vfs: add vfs_ref_from_vp
    
    This generalizes what vop_stdgetwritemount used to be doing.
    
    Reviewed by:    kib
    Differential Revision:  https://reviews.freebsd.org/D28695
---
 sys/kern/vfs_default.c | 25 +------------------------
 sys/kern/vfs_mount.c   | 38 ++++++++++++++++++++++++++++++++++++++
 sys/sys/mount.h        |  1 +
 3 files changed, 40 insertions(+), 24 deletions(-)

diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c
index 3c428d7b7511..4b9b1b43f1ce 100644
--- a/sys/kern/vfs_default.c
+++ b/sys/kern/vfs_default.c
@@ -680,7 +680,6 @@ vop_stdgetwritemount(ap)
        } */ *ap;
 {
        struct mount *mp;
-       struct mount_pcpu *mpcpu;
        struct vnode *vp;
 
        /*
@@ -693,29 +692,7 @@ vop_stdgetwritemount(ap)
         * with releasing it.
         */
        vp = ap->a_vp;
-       mp = vp->v_mount;
-       if (mp == NULL) {
-               *(ap->a_mpp) = NULL;
-               return (0);
-       }
-       if (vfs_op_thread_enter(mp, mpcpu)) {
-               if (mp == vp->v_mount) {
-                       vfs_mp_count_add_pcpu(mpcpu, ref, 1);
-                       vfs_op_thread_exit(mp, mpcpu);
-               } else {
-                       vfs_op_thread_exit(mp, mpcpu);
-                       mp = NULL;
-               }
-       } else {
-               MNT_ILOCK(mp);
-               if (mp == vp->v_mount) {
-                       MNT_REF(mp);
-                       MNT_IUNLOCK(mp);
-               } else {
-                       MNT_IUNLOCK(mp);
-                       mp = NULL;
-               }
-       }
+       mp = vfs_ref_from_vp(vp);
        *(ap->a_mpp) = mp;
        return (0);
 }
diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c
index b3870e46c5e9..e20e1520f677 100644
--- a/sys/kern/vfs_mount.c
+++ b/sys/kern/vfs_mount.c
@@ -449,6 +449,44 @@ sys_nmount(struct thread *td, struct nmount_args *uap)
  * Various utility functions
  */
 
+/*
+ * Get a reference on a mount point from a vnode.
+ *
+ * The vnode is allowed to be passed unlocked and race against dooming. Note in
+ * such case there are no guarantees the referenced mount point will still be
+ * associated with it after the function returns.
+ */
+struct mount *
+vfs_ref_from_vp(struct vnode *vp)
+{
+       struct mount *mp;
+       struct mount_pcpu *mpcpu;
+
+       mp = atomic_load_ptr(&vp->v_mount);
+       if (__predict_false(mp == NULL)) {
+               return (mp);
+       }
+       if (vfs_op_thread_enter(mp, mpcpu)) {
+               if (__predict_true(mp == vp->v_mount)) {
+                       vfs_mp_count_add_pcpu(mpcpu, ref, 1);
+                       vfs_op_thread_exit(mp, mpcpu);
+               } else {
+                       vfs_op_thread_exit(mp, mpcpu);
+                       mp = NULL;
+               }
+       } else {
+               MNT_ILOCK(mp);
+               if (mp == vp->v_mount) {
+                       MNT_REF(mp);
+                       MNT_IUNLOCK(mp);
+               } else {
+                       MNT_IUNLOCK(mp);
+                       mp = NULL;
+               }
+       }
+       return (mp);
+}
+
 void
 vfs_ref(struct mount *mp)
 {
diff --git a/sys/sys/mount.h b/sys/sys/mount.h
index f965dd72d7ba..9ae5f58e5218 100644
--- a/sys/sys/mount.h
+++ b/sys/sys/mount.h
@@ -997,6 +997,7 @@ void        vfs_mount_error(struct mount *, const char *, 
...);
 void   vfs_mountroot(void);                    /* mount our root filesystem */
 void   vfs_mountedfrom(struct mount *, const char *from);
 void   vfs_notify_upper(struct vnode *, int);
+struct mount *vfs_ref_from_vp(struct vnode *);
 void   vfs_ref(struct mount *);
 void   vfs_rel(struct mount *);
 struct mount *vfs_mount_alloc(struct vnode *, struct vfsconf *, const char *,
_______________________________________________
dev-commits-src-main@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-main
To unsubscribe, send any mail to "dev-commits-src-main-unsubscr...@freebsd.org"

Reply via email to