git: 30a5ba9ded03 - stable/14 - sysvshm: add shmobjinfo() function to find key/seq of the segment backed by obj

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Tue, 15 Oct 2024 15:05:24 UTC
The branch stable/14 has been updated by kib:

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

commit 30a5ba9ded0321410345cb52cfe8ad0301f7a199
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2024-10-05 09:14:15 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2024-10-15 14:50:16 +0000

    sysvshm: add shmobjinfo() function to find key/seq of the segment backed by obj
    
    (cherry picked from commit b72029589e64e04b8f9714ad8535b723276e2e02)
---
 sys/kern/sysv_ipc.c | 11 +++++++++++
 sys/kern/sysv_shm.c | 27 +++++++++++++++++++++++++++
 sys/sys/ipc.h       |  3 +++
 sys/sys/shm.h       |  2 ++
 4 files changed, 43 insertions(+)

diff --git a/sys/kern/sysv_ipc.c b/sys/kern/sysv_ipc.c
index dc7cac13fdd8..7240d7cd7150 100644
--- a/sys/kern/sysv_ipc.c
+++ b/sys/kern/sysv_ipc.c
@@ -50,6 +50,8 @@
 #ifndef SYSVSHM
 void (*shmfork_hook)(struct proc *, struct proc *) = NULL;
 void (*shmexit_hook)(struct vmspace *) = NULL;
+void (*shmobjinfo_hook)(struct vm_object *, key_t *key,
+    unsigned short *seq) = NULL;
 
 /* called from kern_fork.c */
 void
@@ -66,6 +68,15 @@ shmexit(struct vmspace *vm)
 	if (shmexit_hook != NULL)
 		shmexit_hook(vm);
 }
+
+void
+shmobjinfo(struct vm_object *obj, key_t *key, unsigned short *seq)
+{
+	*key = 0;	/* For non-present sysvshm.ko */
+	*seq = 0;
+	if (shmobjinfo_hook != NULL)
+		shmobjinfo_hook(obj, key, seq);
+}
 #endif
 
 /*
diff --git a/sys/kern/sysv_shm.c b/sys/kern/sysv_shm.c
index 4dbe77f19b07..60e3fe92a4b7 100644
--- a/sys/kern/sysv_shm.c
+++ b/sys/kern/sysv_shm.c
@@ -133,6 +133,8 @@ static int shmunload(void);
 #ifndef SYSVSHM
 static void shmexit_myhook(struct vmspace *vm);
 static void shmfork_myhook(struct proc *p1, struct proc *p2);
+static void shmobjinfo_myhook(vm_object_t obj, key_t *key,
+    unsigned short *seq);
 #endif
 static int sysctl_shmsegs(SYSCTL_HANDLER_ARGS);
 static void shm_remove(struct shmid_kernel *, int);
@@ -856,6 +858,29 @@ shmexit_myhook(struct vmspace *vm)
 	}
 }
 
+#ifdef SYSVSHM
+void
+shmobjinfo(vm_object_t obj, key_t *key, unsigned short *seq)
+#else
+static void
+shmobjinfo_myhook(vm_object_t obj, key_t *key, unsigned short *seq)
+#endif
+{
+	int i;
+
+	*key = 0;	/* For statically compiled-in sysv_shm.c */
+	*seq = 0;
+	SYSVSHM_LOCK();
+	for (i = 0; i < shmalloced; i++) {
+		if (shmsegs[i].object == obj) {
+			*key = shmsegs[i].u.shm_perm.key;
+			*seq = shmsegs[i].u.shm_perm.seq;
+			break;
+		}
+	}
+	SYSVSHM_UNLOCK();
+}
+
 static void
 shmrealloc(void)
 {
@@ -962,6 +987,7 @@ shminit(void)
 #ifndef SYSVSHM
 	shmexit_hook = &shmexit_myhook;
 	shmfork_hook = &shmfork_myhook;
+	shmobjinfo_hook = &shmobjinfo_myhook;
 #endif
 
 	/* Set current prisons according to their allow.sysvipc. */
@@ -1029,6 +1055,7 @@ shmunload(void)
 #ifndef SYSVSHM
 	shmexit_hook = NULL;
 	shmfork_hook = NULL;
+	shmobjinfo_hook = NULL;
 #endif
 	sx_destroy(&sysvshmsx);
 	return (0);
diff --git a/sys/sys/ipc.h b/sys/sys/ipc.h
index 95a01be20eec..ce0f550900fb 100644
--- a/sys/sys/ipc.h
+++ b/sys/sys/ipc.h
@@ -129,6 +129,7 @@ struct ipc_perm {
 struct thread;
 struct proc;
 struct vmspace;
+struct vm_object;
 
 #if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
     defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
@@ -139,6 +140,8 @@ void	ipcperm_new2old(struct ipc_perm *, struct ipc_perm_old *);
 int	ipcperm(struct thread *, struct ipc_perm *, int);
 extern void (*shmfork_hook)(struct proc *, struct proc *);
 extern void (*shmexit_hook)(struct vmspace *);
+extern void (*shmobjinfo_hook)(struct vm_object *obj, key_t *key,
+    unsigned short *seq);
 
 #else /* ! _KERNEL */
 
diff --git a/sys/sys/shm.h b/sys/sys/shm.h
index a1aa6ca54c60..15d08becc072 100644
--- a/sys/sys/shm.h
+++ b/sys/sys/shm.h
@@ -149,6 +149,7 @@ struct shm_info {
 #ifdef _KERNEL
 struct proc;
 struct vmspace;
+struct vm_object;
 
 extern struct shminfo	shminfo;
 
@@ -158,6 +159,7 @@ extern struct shminfo	shminfo;
 
 void	shmexit(struct vmspace *);
 void	shmfork(struct proc *, struct proc *);
+void	shmobjinfo(struct vm_object *obj, key_t *key, unsigned short *seq);
 int	kern_get_shmsegs(struct thread *td, struct shmid_kernel **res,
 	    size_t *sz);