diff options
author | Vladimir Kondratyev <wulf@FreeBSD.org> | 2021-09-29 20:12:25 +0000 |
---|---|---|
committer | Vladimir Kondratyev <wulf@FreeBSD.org> | 2021-09-29 20:12:25 +0000 |
commit | a81b36c6d35d74177891860b789dd02b9d1c5851 (patch) | |
tree | c43e6424f821fd29371ff4bf5d522d96343c361b | |
parent | ab4ed843a303ea3e585f8ed3f79873e46d3b3ae3 (diff) | |
download | src-a81b36c6d35d74177891860b789dd02b9d1c5851.tar.gz src-a81b36c6d35d74177891860b789dd02b9d1c5851.zip |
LinuxKPI: Implement get_file_rcu()
get_file_rcu() grabs a file if the file->f_count is not zero.
Required by drm-kmod 5.6
Reviewed by: hselasky, manu (previous version)
MFC after: 2 weeks
Differential revision: https://reviews.freebsd.org/D31672
-rw-r--r-- | sys/compat/linuxkpi/common/include/linux/fs.h | 9 | ||||
-rw-r--r-- | sys/compat/linuxkpi/common/src/linux_compat.c | 4 |
2 files changed, 12 insertions, 1 deletions
diff --git a/sys/compat/linuxkpi/common/include/linux/fs.h b/sys/compat/linuxkpi/common/include/linux/fs.h index 38911c276216..eaf806b6732c 100644 --- a/sys/compat/linuxkpi/common/include/linux/fs.h +++ b/sys/compat/linuxkpi/common/include/linux/fs.h @@ -108,6 +108,8 @@ struct linux_file { /* pointer to associated character device, if any */ struct linux_cdev *f_cdev; + + struct rcu_head rcu; }; #define file linux_file @@ -254,6 +256,13 @@ get_file(struct linux_file *f) return (f); } +static inline bool +get_file_rcu(struct linux_file *f) +{ + return (refcount_acquire_if_not_zero( + f->_file == NULL ? &f->f_count : &f->_file->f_count)); +} + static inline struct inode * igrab(struct inode *inode) { diff --git a/sys/compat/linuxkpi/common/src/linux_compat.c b/sys/compat/linuxkpi/common/src/linux_compat.c index 7ea33c9a0d8d..f15b9396525c 100644 --- a/sys/compat/linuxkpi/common/src/linux_compat.c +++ b/sys/compat/linuxkpi/common/src/linux_compat.c @@ -90,6 +90,7 @@ __FBSDID("$FreeBSD$"); #include <linux/poll.h> #include <linux/smp.h> #include <linux/wait_bit.h> +#include <linux/rcupdate.h> #if defined(__i386__) || defined(__amd64__) #include <asm/smp.h> @@ -472,7 +473,7 @@ linux_file_free(struct linux_file *filp) if (filp->_file == NULL) { if (filp->f_shmem != NULL) vm_object_deallocate(filp->f_shmem); - kfree(filp); + kfree_rcu(filp, rcu); } else { /* * The close method of the character device or file @@ -1538,6 +1539,7 @@ linux_file_close(struct file *file, struct thread *td) ldev = filp->f_cdev; if (ldev != NULL) linux_cdev_deref(ldev); + linux_synchronize_rcu(RCU_TYPE_REGULAR); kfree(filp); return (error); |