Skip to content

Commit

Permalink
Fix fd leaks on device nodes
Browse files Browse the repository at this point in the history
  • Loading branch information
tbodt committed Jan 11, 2019
1 parent 5aeb536 commit ff83d8e
Show file tree
Hide file tree
Showing 5 changed files with 17 additions and 8 deletions.
1 change: 1 addition & 0 deletions fs/fake.c
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,7 @@ const struct fs_ops fakefs = {
.symlink = fakefs_symlink,
.mknod = fakefs_mknod,

.close = realfs_close,
.stat = fakefs_stat,
.fstat = fakefs_fstat,
.flock = realfs_flock,
Expand Down
9 changes: 7 additions & 2 deletions fs/fd.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ int fd_close(struct fd *fd) {
unlock(&fd->poll_lock);
if (fd->ops->close)
err = fd->ops->close(fd);
// see comment in close in kernel/fs.h
if (fd->mount->fs->close && fd->mount->fs->close != fd->ops->close) {
int new_err = fd->mount->fs->close(fd);
if (new_err < 0)
err = new_err;
}
free(fd);
}
return err;
Expand Down Expand Up @@ -241,8 +247,7 @@ dword_t sys_dup2(fd_t f, fd_t new_f) {
if (err < 0)
return err;
f_close(new_f);
fd->refcount++;
table->files[new_f] = fd;
table->files[new_f] = fd_retain(fd);
return new_f;
}

Expand Down
8 changes: 2 additions & 6 deletions fs/fd.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,6 @@ struct fd {

// fd data
union {
// realfs/fakefs
struct {
DIR *dir;
};
// proc
struct {
struct proc_entry proc_entry;
Expand Down Expand Up @@ -55,8 +51,8 @@ struct fd {

// fs/inode data
struct mount *mount;
// seeks on this fd require the lock
int real_fd;
int real_fd; // seeks on this fd require the lock
DIR *dir;
struct statbuf stat; // for adhoc fs

// these are used for a variety of things related to the fd
Expand Down
1 change: 1 addition & 0 deletions fs/real.c
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,7 @@ const struct fs_ops realfs = {
.symlink = realfs_symlink,
.mknod = realfs_mknod,

.close = realfs_close,
.stat = realfs_stat,
.fstat = realfs_fstat,
.setattr = realfs_setattr,
Expand Down
6 changes: 6 additions & 0 deletions kernel/fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,12 @@ struct fs_ops {
int (*symlink)(struct mount *mount, const char *target, const char *link);
int (*mknod)(struct mount *mount, const char *path, mode_t_ mode, dev_t_ dev);

// There's a close function in both the fs and fd to handle device files
// where, for instance, there's a real_fd needed for getpath and also a tty
// reference, and both need to be released when the fd is closed.
// If they are the same function, it will only be called once.
int (*close)(struct fd *fd);

int (*stat)(struct mount *mount, const char *path, struct statbuf *stat, bool follow_links);
int (*fstat)(struct fd *fd, struct statbuf *stat);
int (*setattr)(struct mount *mount, const char *path, struct attr attr);
Expand Down

0 comments on commit ff83d8e

Please sign in to comment.