diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -4194,9 +4194,9 @@ if (fdp == NULL) continue; FILEDESC_SLOCK(fdp); + if (refcount_load(&fdp->fd_refcnt) == 0) + goto nextproc; FILEDESC_FOREACH_FP(fdp, n, fp) { - if (refcount_load(&fdp->fd_refcnt) == 0) - break; xf.xf_fd = n; xf.xf_file = (uintptr_t)fp; xf.xf_data = (uintptr_t)fp->f_data; @@ -4207,9 +4207,16 @@ xf.xf_offset = foffset_get(fp); xf.xf_flag = fp->f_flag; error = SYSCTL_OUT(req, &xf, sizeof(xf)); - if (error) + + /* + * There is no need to re-check the fdtable refcount + * here since the filedesc lock is not dropped in the + * loop body. + */ + if (error != 0) break; } +nextproc: FILEDESC_SUNLOCK(fdp); fddrop(fdp); if (error) @@ -4469,9 +4476,9 @@ if (pwd != NULL) pwd_drop(pwd); FILEDESC_SLOCK(fdp); + if (refcount_load(&fdp->fd_refcnt) == 0) + goto skip; FILEDESC_FOREACH_FP(fdp, i, fp) { - if (refcount_load(&fdp->fd_refcnt) == 0) - break; #ifdef CAPABILITIES rights = *cap_rights(fdp, i); #else /* !CAPABILITIES */ @@ -4484,9 +4491,10 @@ * loop continues. */ error = export_file_to_sb(fp, i, &rights, efbuf); - if (error != 0) + if (error != 0 || refcount_load(&fdp->fd_refcnt) == 0) break; } +skip: FILEDESC_SUNLOCK(fdp); fail: if (fdp != NULL) @@ -4633,18 +4641,19 @@ if (pwd != NULL) pwd_drop(pwd); FILEDESC_SLOCK(fdp); + if (refcount_load(&fdp->fd_refcnt) == 0) + goto skip; FILEDESC_FOREACH_FP(fdp, i, fp) { - if (refcount_load(&fdp->fd_refcnt) == 0) - break; export_file_to_kinfo(fp, i, NULL, kif, fdp, KERN_FILEDESC_PACK_KINFO); FILEDESC_SUNLOCK(fdp); kinfo_to_okinfo(kif, okif); error = SYSCTL_OUT(req, okif, sizeof(*okif)); FILEDESC_SLOCK(fdp); - if (error) + if (error != 0 || refcount_load(&fdp->fd_refcnt) == 0) break; } +skip: FILEDESC_SUNLOCK(fdp); fddrop(fdp); pddrop(pdp);