Skip to content

Commit

Permalink
[PATCH] sanitize locate_fd()
Browse files Browse the repository at this point in the history
* 'file' argument is unused; lose it.
* move setting flags from the caller (dupfd()) to locate_fd();
  pass cloexec flag as new argument.  Note that files_fdtable()
  that used to be in dupfd() isn't needed in the place in
  locate_fd() where the moved code ends up - we know that ->file_lock
  hadn't been dropped since the last time we calculated fdt because
  we can get there only if expand_files() returns 0 and it doesn't
  drop/reacquire in that case.
* move getting/dropping ->file_lock into locate_fd().  Now the caller
  doesn't need to do anything with files_struct *files anymore and
  we can move that inside locate_fd() as well, killing the
  struct files_struct * argument.

At that point locate_fd() is extremely similar to get_unused_fd_flags()
and the next patches will merge those two.

Signed-off-by: Al Viro <[email protected]>
  • Loading branch information
Al Viro committed Apr 25, 2008
1 parent 3b12538 commit f8f9570
Showing 1 changed file with 14 additions and 26 deletions.
40 changes: 14 additions & 26 deletions fs/fcntl.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,16 @@ static int get_close_on_exec(unsigned int fd)
* file_lock held for write.
*/

static int locate_fd(struct files_struct *files,
struct file *file, unsigned int orig_start)
static int locate_fd(unsigned int orig_start, int cloexec)
{
struct files_struct *files = current->files;
unsigned int newfd;
unsigned int start;
int error;
struct fdtable *fdt;

spin_lock(&files->file_lock);

error = -EINVAL;
if (orig_start >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
goto out;
Expand Down Expand Up @@ -97,42 +99,28 @@ static int locate_fd(struct files_struct *files,
if (error)
goto repeat;

/*
* We reacquired files_lock, so we are safe as long as
* we reacquire the fdtable pointer and use it while holding
* the lock, no one can free it during that time.
*/
if (start <= files->next_fd)
files->next_fd = newfd + 1;

FD_SET(newfd, fdt->open_fds);
if (cloexec)
FD_SET(newfd, fdt->close_on_exec);
else
FD_CLR(newfd, fdt->close_on_exec);
error = newfd;

out:
spin_unlock(&files->file_lock);
return error;
}

static int dupfd(struct file *file, unsigned int start, int cloexec)
{
struct files_struct * files = current->files;
struct fdtable *fdt;
int fd;

spin_lock(&files->file_lock);
fd = locate_fd(files, file, start);
if (fd >= 0) {
/* locate_fd() may have expanded fdtable, load the ptr */
fdt = files_fdtable(files);
FD_SET(fd, fdt->open_fds);
if (cloexec)
FD_SET(fd, fdt->close_on_exec);
else
FD_CLR(fd, fdt->close_on_exec);
spin_unlock(&files->file_lock);
int fd = locate_fd(start, cloexec);
if (fd >= 0)
fd_install(fd, file);
} else {
spin_unlock(&files->file_lock);
else
fput(file);
}

return fd;
}
Expand Down

0 comments on commit f8f9570

Please sign in to comment.