Skip to content

Commit

Permalink
Fix file descriptor leak on pool import.
Browse files Browse the repository at this point in the history
Descriptor leak can be easily reproduced by doing:

	# zpool import tank
	# sysctl kern.openfiles
	# zpool export tank; zpool import tank
	# sysctl kern.openfiles

We were leaking four file descriptors on every import.

Similar leak most likely existed when using file-based VDEVs.

Signed-off-by: Pawel Jakub Dawidek <[email protected]>
  • Loading branch information
pjd committed Dec 28, 2023
1 parent 4cf4bc7 commit 0ffc915
Showing 1 changed file with 47 additions and 12 deletions.
59 changes: 47 additions & 12 deletions module/os/freebsd/zfs/zfs_file_os.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,26 +50,61 @@ int
zfs_file_open(const char *path, int flags, int mode, zfs_file_t **fpp)
{
struct thread *td;
int rc, fd;
struct vnode *vp;
struct file *fp;
struct nameidata nd;
int error;

td = curthread;
pwd_ensure_dirs();
/* 12.x doesn't take a const char * */
rc = kern_openat(td, AT_FDCWD, __DECONST(char *, path),
UIO_SYSSPACE, flags, mode);
if (rc)
return (SET_ERROR(rc));
fd = td->td_retval[0];
td->td_retval[0] = 0;
if (fget(curthread, fd, &cap_no_rights, fpp))
kern_close(td, fd);

KASSERT((flags & (O_EXEC | O_PATH)) == 0,
("invalid flags: 0x%x", flags));
KASSERT((flags & O_ACCMODE) != O_ACCMODE,
("invalid flags: 0x%x", flags));
flags = FFLAGS(flags);

error = falloc_noinstall(td, &fp);
if (error != 0) {
return (error);
}
fp->f_flag = flags & FMASK;

NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, path);
error = vn_open(&nd, &flags, mode, fp);
if (error != 0) {
falloc_abort(td, fp);
return (SET_ERROR(error));
}
NDFREE_PNBUF(&nd);
vp = nd.ni_vp;
fp->f_vnode = vp;
if (fp->f_ops == &badfileops) {
finit_vnode(fp, flags, NULL, &vnops);
}
VOP_UNLOCK(vp);
if (vp->v_type != VREG) {
zfs_file_close(fp);
return (SET_ERROR(EACCES));
}

if (flags & O_TRUNC) {
error = fo_truncate(fp, 0, td->td_ucred, td);
if (error != 0) {
zfs_file_close(fp);
return (SET_ERROR(error));
}
}

*fpp = fp;

return (0);
}

void
zfs_file_close(zfs_file_t *fp)
{
fo_close(fp, curthread);
fdrop(fp, curthread);
}

static int
Expand Down Expand Up @@ -260,7 +295,7 @@ zfs_file_get(int fd)
void
zfs_file_put(zfs_file_t *fp)
{
fdrop(fp, curthread);
zfs_file_close(fp);
}

loff_t
Expand Down

0 comments on commit 0ffc915

Please sign in to comment.