mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-11-18 10:21:01 +03:00
8415c3c170
Callers of zfs_file_get and zfs_file_put can corrupt the reference counts for the file structure resulting in a panic or a soft lockup. When zfs send/recv runs, it will add a reference count to the open file, and begin to send or recv the stream. If the file descriptor is closed, then when dmu_recv_stream() or dmu_send() return we will call zfs_file_put to remove the reference we placed on the file structure. Unfortunately, because zfs_file_put() uses the file descriptor to lookup the file structure, it may end up finding that the file descriptor table no longer contains the file struct, thus leaking the file structure. Or it might end up finding a file descriptor for a different file and blindly updating its reference counts. Other failure modes probably exists. This change reworks the zfs_file_[get|put] interface to not rely on the file descriptor but instead pass the zfs_file_t pointer around. Reviewed-by: Matthew Ahrens <mahrens@delphix.com> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Mark Maybee <mark.maybee@delphix.com> Reviewed-by: Ryan Moeller <ryan@iXsystems.com> Co-authored-by: Allan Jude <allan@klarasystems.com> Signed-off-by: George Wilson <gwilson@delphix.com> External-issue: DLPX-76119 Closes #12299
64 lines
1.7 KiB
C
64 lines
1.7 KiB
C
/*
|
|
* CDDL HEADER START
|
|
*
|
|
* The contents of this file are subject to the terms of the
|
|
* Common Development and Distribution License (the "License").
|
|
* You may not use this file except in compliance with the License.
|
|
*
|
|
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
|
* or http://www.opensolaris.org/os/licensing.
|
|
* See the License for the specific language governing permissions
|
|
* and limitations under the License.
|
|
*
|
|
* When distributing Covered Code, include this CDDL HEADER in each
|
|
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
|
* If applicable, add the following below this CDDL HEADER, with the
|
|
* fields enclosed by brackets "[]" replaced with your own identifying
|
|
* information: Portions Copyright [yyyy] [name of copyright owner]
|
|
*
|
|
* CDDL HEADER END
|
|
*/
|
|
|
|
/*
|
|
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
|
|
* Copyright (c) 2020 by Delphix. All rights reserved.
|
|
*/
|
|
|
|
#ifndef _SYS_ZFS_ONEXIT_H
|
|
#define _SYS_ZFS_ONEXIT_H
|
|
|
|
#include <sys/zfs_context.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#ifdef _KERNEL
|
|
|
|
typedef struct zfs_onexit {
|
|
kmutex_t zo_lock;
|
|
list_t zo_actions;
|
|
} zfs_onexit_t;
|
|
|
|
typedef struct zfs_onexit_action_node {
|
|
list_node_t za_link;
|
|
void (*za_func)(void *);
|
|
void *za_data;
|
|
} zfs_onexit_action_node_t;
|
|
|
|
extern void zfs_onexit_init(zfs_onexit_t **zo);
|
|
extern void zfs_onexit_destroy(zfs_onexit_t *zo);
|
|
|
|
#endif
|
|
|
|
extern zfs_file_t *zfs_onexit_fd_hold(int fd, minor_t *minorp);
|
|
extern void zfs_onexit_fd_rele(zfs_file_t *);
|
|
extern int zfs_onexit_add_cb(minor_t minor, void (*func)(void *), void *data,
|
|
uint64_t *action_handle);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* _SYS_ZFS_ONEXIT_H */
|