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 27, 2023
1 parent 4cf4bc7 commit bf51e73
Showing 1 changed file with 42 additions and 12 deletions.
54 changes: 42 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,56 @@ 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);

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

NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, path);
flags = FFLAGS(flags);
error = vn_open(&nd, &flags, 0, 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 +290,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 bf51e73

Please sign in to comment.