mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-18 10:35:55 +00:00
fd: make the common case in filecaps_copy work lockless
The filedesc lock is only needed if ioctls caps are present, which is a rare situation. This is a step towards reducing the scope of the filedesc lock.
This commit is contained in:
parent
40ea8e710e
commit
d7832811a7
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=287539
@ -911,7 +911,7 @@ kern_dup(struct thread *td, u_int mode, int flags, int old, int new)
|
||||
#endif
|
||||
filecaps_free(&newfde->fde_caps);
|
||||
memcpy(newfde, oldfde, fde_change_size);
|
||||
filecaps_copy(&oldfde->fde_caps, &newfde->fde_caps);
|
||||
filecaps_copy(&oldfde->fde_caps, &newfde->fde_caps, true);
|
||||
if ((flags & FDDUP_FLAG_CLOEXEC) != 0)
|
||||
newfde->fde_flags = oldfde->fde_flags | UF_EXCLOSE;
|
||||
else
|
||||
@ -1433,21 +1433,31 @@ filecaps_init(struct filecaps *fcaps)
|
||||
|
||||
/*
|
||||
* Copy filecaps structure allocating memory for ioctls array if needed.
|
||||
*
|
||||
* The last parameter indicates whether the fdtable is locked. If it is not and
|
||||
* ioctls are encountered, copying fails and the caller must lock the table.
|
||||
*
|
||||
* Note that if the table was not locked, the caller has to check the relevant
|
||||
* sequence counter to determine whether the operation was successful.
|
||||
*/
|
||||
void
|
||||
filecaps_copy(const struct filecaps *src, struct filecaps *dst)
|
||||
int
|
||||
filecaps_copy(const struct filecaps *src, struct filecaps *dst, bool locked)
|
||||
{
|
||||
size_t size;
|
||||
|
||||
*dst = *src;
|
||||
if (src->fc_ioctls != NULL) {
|
||||
if (src->fc_ioctls == NULL)
|
||||
return (0);
|
||||
if (!locked)
|
||||
return (1);
|
||||
|
||||
KASSERT(src->fc_nioctls > 0,
|
||||
("fc_ioctls != NULL, but fc_nioctls=%hd", src->fc_nioctls));
|
||||
|
||||
size = sizeof(src->fc_ioctls[0]) * src->fc_nioctls;
|
||||
dst->fc_ioctls = malloc(size, M_FILECAPS, M_WAITOK);
|
||||
bcopy(src->fc_ioctls, dst->fc_ioctls, size);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1956,7 +1966,7 @@ fdcopy(struct filedesc *fdp)
|
||||
}
|
||||
nfde = &newfdp->fd_ofiles[i];
|
||||
*nfde = *ofde;
|
||||
filecaps_copy(&ofde->fde_caps, &nfde->fde_caps);
|
||||
filecaps_copy(&ofde->fde_caps, &nfde->fde_caps, true);
|
||||
fhold(nfde->fde_file);
|
||||
fdused_init(newfdp, i);
|
||||
newfdp->fd_lastfile = i;
|
||||
@ -2012,7 +2022,7 @@ fdcopy_remapped(struct filedesc *fdp, const int *fds, size_t nfds,
|
||||
}
|
||||
nfde = &newfdp->fd_ofiles[i];
|
||||
*nfde = *ofde;
|
||||
filecaps_copy(&ofde->fde_caps, &nfde->fde_caps);
|
||||
filecaps_copy(&ofde->fde_caps, &nfde->fde_caps, true);
|
||||
fhold(nfde->fde_file);
|
||||
fdused_init(newfdp, i);
|
||||
newfdp->fd_lastfile = i;
|
||||
@ -2723,7 +2733,7 @@ fgetvp_rights(struct thread *td, int fd, cap_rights_t *needrightsp,
|
||||
|
||||
*vpp = fp->f_vnode;
|
||||
vref(*vpp);
|
||||
filecaps_copy(&fdp->fd_ofiles[fd].fde_caps, havecaps);
|
||||
filecaps_copy(&fdp->fd_ofiles[fd].fde_caps, havecaps, true);
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -2938,7 +2948,7 @@ dupfdopen(struct thread *td, struct filedesc *fdp, int dfd, int mode,
|
||||
seq_write_begin(&newfde->fde_seq);
|
||||
#endif
|
||||
memcpy(newfde, oldfde, fde_change_size);
|
||||
filecaps_copy(&oldfde->fde_caps, &newfde->fde_caps);
|
||||
filecaps_copy(&oldfde->fde_caps, &newfde->fde_caps, true);
|
||||
#ifdef CAPABILITIES
|
||||
seq_write_end(&newfde->fde_seq);
|
||||
#endif
|
||||
|
@ -1972,7 +1972,7 @@ unp_internalize(struct mbuf **controlp, struct thread *td)
|
||||
fdep[i] = fdev;
|
||||
fdep[i]->fde_file = fde->fde_file;
|
||||
filecaps_copy(&fde->fde_caps,
|
||||
&fdep[i]->fde_caps);
|
||||
&fdep[i]->fde_caps, true);
|
||||
unp_internalize_fp(fdep[i]->fde_file);
|
||||
}
|
||||
FILEDESC_SUNLOCK(fdesc);
|
||||
|
@ -153,7 +153,8 @@ enum {
|
||||
struct thread;
|
||||
|
||||
void filecaps_init(struct filecaps *fcaps);
|
||||
void filecaps_copy(const struct filecaps *src, struct filecaps *dst);
|
||||
int filecaps_copy(const struct filecaps *src, struct filecaps *dst,
|
||||
bool locked);
|
||||
void filecaps_move(struct filecaps *src, struct filecaps *dst);
|
||||
void filecaps_free(struct filecaps *fcaps);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user