aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/kern_descrip.c
diff options
context:
space:
mode:
authorMateusz Guzik <mjg@FreeBSD.org>2022-02-01 16:58:12 +0000
committerMateusz Guzik <mjg@FreeBSD.org>2022-02-11 12:29:26 +0000
commit45bb8beacc2fadbbc32428df0f2f5683863df289 (patch)
tree8f8fb8fac12a3b8437b1e9fe34f6eed1fc5b3e26 /sys/kern/kern_descrip.c
parent62849eef5b573b9907257f20318f4bd48fcf7b3a (diff)
downloadsrc-45bb8beacc2fadbbc32428df0f2f5683863df289.tar.gz
src-45bb8beacc2fadbbc32428df0f2f5683863df289.zip
fd: elide one acquire fence in fget_unlocked_seq
Still validate we got the stable state before returning an error though.
Diffstat (limited to 'sys/kern/kern_descrip.c')
-rw-r--r--sys/kern/kern_descrip.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index c4f435002907..e5ffdb01255f 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -3060,13 +3060,19 @@ fget_unlocked_seq(struct filedesc *fdp, int fd, cap_rights_t *needrightsp,
fde = &fdt->fdt_ofiles[fd];
haverights = *cap_rights_fde_inline(fde);
fp = fde->fde_file;
- if (!seqc_consistent(fd_seqc(fdt, fd), seq))
+ if (__predict_false(fp == NULL)) {
+ if (seqc_consistent(fd_seqc(fdt, fd), seq))
+ return (EBADF);
+ fdt = atomic_load_ptr(&fdp->fd_files);
continue;
- if (__predict_false(fp == NULL))
- return (EBADF);
+ }
error = cap_check_inline(&haverights, needrightsp);
- if (__predict_false(error != 0))
- return (error);
+ if (__predict_false(error != 0)) {
+ if (seqc_consistent(fd_seqc(fdt, fd), seq))
+ return (error);
+ fdt = atomic_load_ptr(&fdp->fd_files);
+ continue;
+ }
if (__predict_false(!refcount_acquire_if_not_zero(&fp->f_count))) {
fdt = atomic_load_ptr(&fdp->fd_files);
continue;