Commit ce08b62d authored by Oleg Nesterov's avatar Oleg Nesterov Committed by Al Viro

change close_files() to use rcu_dereference_raw(files->fdt)

put_files_struct() and close_files() do rcu_read_lock() to make
rcu_dereference_check_fdtable() happy.

This looks a bit ugly, files_fdtable() just reads the pointer,
we can simply use rcu_dereference_raw() to avoid the warning.

The patch also changes close_files() to return fdt, this avoids
another rcu_read_lock()/files_fdtable() in put_files_struct().

I think close_files() needs more cleanups:

	- we do not need xchg() exactly because we are the last
	  user of this files_struct

	- "if (file)" should be turned into WARN_ON(!file)
Signed-off-by: default avatarOleg Nesterov <oleg@redhat.com>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent a8d4b834
......@@ -348,21 +348,16 @@ struct files_struct *dup_fd(struct files_struct *oldf, int *errorp)
return NULL;
}
static void close_files(struct files_struct * files)
static struct fdtable *close_files(struct files_struct * files)
{
int i, j;
struct fdtable *fdt;
j = 0;
/*
* It is safe to dereference the fd table without RCU or
* ->file_lock because this is the last reference to the
* files structure. But use RCU to shut RCU-lockdep up.
* files structure.
*/
rcu_read_lock();
fdt = files_fdtable(files);
rcu_read_unlock();
struct fdtable *fdt = rcu_dereference_raw(files->fdt);
int i, j = 0;
for (;;) {
unsigned long set;
i = j * BITS_PER_LONG;
......@@ -381,6 +376,8 @@ static void close_files(struct files_struct * files)
set >>= 1;
}
}
return fdt;
}
struct files_struct *get_files_struct(struct task_struct *task)
......@@ -398,14 +395,9 @@ struct files_struct *get_files_struct(struct task_struct *task)
void put_files_struct(struct files_struct *files)
{
struct fdtable *fdt;
if (atomic_dec_and_test(&files->count)) {
close_files(files);
/* not really needed, since nobody can see us */
rcu_read_lock();
fdt = files_fdtable(files);
rcu_read_unlock();
struct fdtable *fdt = close_files(files);
/* free the arrays if they are not embedded */
if (fdt != &files->fdtab)
__free_fdtable(fdt);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment