Create a dedicated function for ensuring that cdir and rdir are populated.
Previously several places were doing it on its own, partially incorrectly (e.g. without the filedesc locked) or even actively harmful by populating jdir or assigning rootvnode without vrefing it. Reviewed by: kib
This commit is contained in:
parent
c71e9ab863
commit
a85ed5531d
@ -2123,18 +2123,7 @@ ctl_be_block_open(struct ctl_be_block_softc *softc,
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (!curthread->td_proc->p_fd->fd_cdir) {
|
||||
curthread->td_proc->p_fd->fd_cdir = rootvnode;
|
||||
VREF(rootvnode);
|
||||
}
|
||||
if (!curthread->td_proc->p_fd->fd_rdir) {
|
||||
curthread->td_proc->p_fd->fd_rdir = rootvnode;
|
||||
VREF(rootvnode);
|
||||
}
|
||||
if (!curthread->td_proc->p_fd->fd_jdir) {
|
||||
curthread->td_proc->p_fd->fd_jdir = rootvnode;
|
||||
VREF(rootvnode);
|
||||
}
|
||||
pwd_ensure_dirs();
|
||||
|
||||
again:
|
||||
NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, be_lun->dev_path, curthread);
|
||||
|
@ -67,21 +67,10 @@ static void *
|
||||
kobj_open_file_vnode(const char *file)
|
||||
{
|
||||
struct thread *td = curthread;
|
||||
struct filedesc *fd;
|
||||
struct nameidata nd;
|
||||
int error, flags;
|
||||
|
||||
fd = td->td_proc->p_fd;
|
||||
FILEDESC_XLOCK(fd);
|
||||
if (fd->fd_rdir == NULL) {
|
||||
fd->fd_rdir = rootvnode;
|
||||
vref(fd->fd_rdir);
|
||||
}
|
||||
if (fd->fd_cdir == NULL) {
|
||||
fd->fd_cdir = rootvnode;
|
||||
vref(fd->fd_cdir);
|
||||
}
|
||||
FILEDESC_XUNLOCK(fd);
|
||||
pwd_ensure_dirs();
|
||||
|
||||
flags = FREAD | O_NOFOLLOW;
|
||||
NDINIT(&nd, LOOKUP, 0, UIO_SYSSPACE, file, td);
|
||||
|
@ -162,7 +162,6 @@ vn_openat(char *pnamep, enum uio_seg seg, int filemode, int createmode,
|
||||
int fd)
|
||||
{
|
||||
struct thread *td = curthread;
|
||||
struct filedesc *fdc;
|
||||
struct nameidata nd;
|
||||
int error, operation;
|
||||
|
||||
@ -179,17 +178,7 @@ vn_openat(char *pnamep, enum uio_seg seg, int filemode, int createmode,
|
||||
}
|
||||
ASSERT(umask == 0);
|
||||
|
||||
fdc = td->td_proc->p_fd;
|
||||
FILEDESC_XLOCK(fdc);
|
||||
if (fdc->fd_rdir == NULL) {
|
||||
fdc->fd_rdir = rootvnode;
|
||||
vref(fdc->fd_rdir);
|
||||
}
|
||||
if (fdc->fd_cdir == NULL) {
|
||||
fdc->fd_cdir = rootvnode;
|
||||
vref(fdc->fd_rdir);
|
||||
}
|
||||
FILEDESC_XUNLOCK(fdc);
|
||||
pwd_ensure_dirs();
|
||||
|
||||
if (startvp != NULL)
|
||||
vref(startvp);
|
||||
|
@ -2817,10 +2817,7 @@ NdisOpenFile(status, filehandle, filelength, filename, highestaddr)
|
||||
|
||||
/* Some threads don't have a current working directory. */
|
||||
|
||||
if (td->td_proc->p_fd->fd_rdir == NULL)
|
||||
td->td_proc->p_fd->fd_rdir = rootvnode;
|
||||
if (td->td_proc->p_fd->fd_cdir == NULL)
|
||||
td->td_proc->p_fd->fd_cdir = rootvnode;
|
||||
pwd_ensure_dirs();
|
||||
|
||||
NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, path, td);
|
||||
|
||||
|
@ -2692,18 +2692,7 @@ xbb_open_backend(struct xbb_softc *xbb)
|
||||
if ((xbb->flags & XBBF_READ_ONLY) == 0)
|
||||
flags |= FWRITE;
|
||||
|
||||
if (!curthread->td_proc->p_fd->fd_cdir) {
|
||||
curthread->td_proc->p_fd->fd_cdir = rootvnode;
|
||||
VREF(rootvnode);
|
||||
}
|
||||
if (!curthread->td_proc->p_fd->fd_rdir) {
|
||||
curthread->td_proc->p_fd->fd_rdir = rootvnode;
|
||||
VREF(rootvnode);
|
||||
}
|
||||
if (!curthread->td_proc->p_fd->fd_jdir) {
|
||||
curthread->td_proc->p_fd->fd_jdir = rootvnode;
|
||||
VREF(rootvnode);
|
||||
}
|
||||
pwd_ensure_dirs();
|
||||
|
||||
again:
|
||||
NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, xbb->dev_name, curthread);
|
||||
|
@ -68,6 +68,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/sbuf.h>
|
||||
#include <sys/signalvar.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/kdb.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/sx.h>
|
||||
#include <sys/syscallsubr.h>
|
||||
@ -308,6 +309,24 @@ fdfree(struct filedesc *fdp, int fd)
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
pwd_ensure_dirs(void)
|
||||
{
|
||||
struct filedesc *fdp;
|
||||
|
||||
fdp = curproc->p_fd;
|
||||
FILEDESC_XLOCK(fdp);
|
||||
if (fdp->fd_cdir == NULL) {
|
||||
fdp->fd_cdir = rootvnode;
|
||||
VREF(rootvnode);
|
||||
}
|
||||
if (fdp->fd_rdir == NULL) {
|
||||
fdp->fd_rdir = rootvnode;
|
||||
VREF(rootvnode);
|
||||
}
|
||||
FILEDESC_XUNLOCK(fdp);
|
||||
}
|
||||
|
||||
/*
|
||||
* System calls on descriptors.
|
||||
*/
|
||||
|
@ -383,19 +383,8 @@ firmware_put(const struct firmware *p, int flags)
|
||||
static void
|
||||
set_rootvnode(void *arg, int npending)
|
||||
{
|
||||
struct thread *td = curthread;
|
||||
struct proc *p = td->td_proc;
|
||||
|
||||
FILEDESC_XLOCK(p->p_fd);
|
||||
if (p->p_fd->fd_cdir == NULL) {
|
||||
p->p_fd->fd_cdir = rootvnode;
|
||||
VREF(rootvnode);
|
||||
}
|
||||
if (p->p_fd->fd_rdir == NULL) {
|
||||
p->p_fd->fd_rdir = rootvnode;
|
||||
VREF(rootvnode);
|
||||
}
|
||||
FILEDESC_XUNLOCK(p->p_fd);
|
||||
pwd_ensure_dirs();
|
||||
|
||||
free(arg, M_TEMP);
|
||||
}
|
||||
|
@ -208,6 +208,7 @@ fd_modified(struct filedesc *fdp, int fd, seq_t seq)
|
||||
/* cdir/rdir/jdir manipulation functions. */
|
||||
void pwd_chdir(struct thread *td, struct vnode *vp);
|
||||
int pwd_chroot(struct thread *td, struct vnode *vp);
|
||||
void pwd_ensure_dirs(void);
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user