git: db5655124ca4 - main - vfs_mount.c: Free exports structures in vfs_destroy_mount()
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 04 Feb 2023 22:46:52 UTC
The branch main has been updated by rmacklem:
URL: https://cgit.FreeBSD.org/src/commit/?id=db5655124ca4047ac397b9421ca4a08868a49ae9
commit db5655124ca4047ac397b9421ca4a08868a49ae9
Author: Rick Macklem <rmacklem@FreeBSD.org>
AuthorDate: 2023-02-04 22:45:23 +0000
Commit: Rick Macklem <rmacklem@FreeBSD.org>
CommitDate: 2023-02-04 22:45:23 +0000
vfs_mount.c: Free exports structures in vfs_destroy_mount()
During testing of exporting file systems in jails, I
noticed that the export structures on a mount
were not being free'd when the mount is dismounted.
This bug appears to have been in the system for a
very long time. It would have resulted in a slow memory
leak when exported file systems were dismounted.
Prior to r362158, freeing the structures during dismount
would not have been safe, since VFS_CHECKEXP() returned
a pointer into an export structure, which might still have been
used by the NFS server for an in-progress RPC when the file system
is dismounted. r362158 fixed this, so it should now be safe
to free the structures in vfs_mount_destroy(), which is what
this patch does.
Reviewed by: kib
MFC after: 1 month
Differential Revision: https://reviews.freebsd.org/D38385
---
sys/kern/vfs_export.c | 7 ++++---
sys/kern/vfs_mount.c | 4 ++++
sys/sys/mount.h | 1 +
3 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/sys/kern/vfs_export.c b/sys/kern/vfs_export.c
index 024011de4c89..cab37ce205ad 100644
--- a/sys/kern/vfs_export.c
+++ b/sys/kern/vfs_export.c
@@ -70,7 +70,6 @@ static MALLOC_DEFINE(M_NETADDR, "export_host", "Export host address structure");
static struct radix_node_head *vfs_create_addrlist_af(
struct radix_node_head **prnh, int off);
#endif
-static void vfs_free_addrlist(struct netexport *nep);
static int vfs_free_netcred(struct radix_node *rn, void *w);
static void vfs_free_addrlist_af(struct radix_node_head **prnh);
static int vfs_hang_addrlist(struct mount *mp, struct netexport *nep,
@@ -274,7 +273,7 @@ vfs_free_addrlist_af(struct radix_node_head **prnh)
/*
* Free the net address hash lists that are hanging off the mount points.
*/
-static void
+void
vfs_free_addrlist(struct netexport *nep)
{
struct ucred *cred;
@@ -285,8 +284,10 @@ vfs_free_addrlist(struct netexport *nep)
vfs_free_addrlist_af(&nep->ne6);
cred = nep->ne_defexported.netc_anon;
- if (cred != NULL)
+ if (cred != NULL) {
crfree(cred);
+ nep->ne_defexported.netc_anon = NULL;
+ }
}
diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c
index 67a72f095786..430bafc8502f 100644
--- a/sys/kern/vfs_mount.c
+++ b/sys/kern/vfs_mount.c
@@ -761,6 +761,10 @@ vfs_mount_destroy(struct mount *mp)
#endif
if (mp->mnt_opt != NULL)
vfs_freeopts(mp->mnt_opt);
+ if (mp->mnt_export != NULL) {
+ vfs_free_addrlist(mp->mnt_export);
+ free(mp->mnt_export, M_MOUNT);
+ }
crfree(mp->mnt_cred);
uma_zfree(mount_zone, mp);
}
diff --git a/sys/sys/mount.h b/sys/sys/mount.h
index 4bfc77b7f1a1..5f02f261b8f4 100644
--- a/sys/sys/mount.h
+++ b/sys/sys/mount.h
@@ -1017,6 +1017,7 @@ void vfs_periodic(struct mount *, int);
int vfs_busy(struct mount *, int);
int vfs_export /* process mount export info */
(struct mount *, struct export_args *);
+void vfs_free_addrlist(struct netexport *);
void vfs_allocate_syncvnode(struct mount *);
void vfs_deallocate_syncvnode(struct mount *);
int vfs_donmount(struct thread *td, uint64_t fsflags,