Commit f36c2943 authored by Eric W. Biederman's avatar Eric W. Biederman
Browse files

file: Replace fcheck_files with files_lookup_fd_rcu

This change renames fcheck_files to files_lookup_fd_rcu.  All of the
remaining callers take the rcu_read_lock before calling this function
so the _rcu suffix is appropriate.  This change also tightens up the
debug check to verify that all callers hold the rcu_read_lock.

All callers that used to call files_check with the files->file_lock
held have now been changed to call files_lookup_fd_locked.

This change of name has helped remind me of which locks and which
guarantees are in place helping me to catch bugs later in the
patchset.

The need for better names became apparent in the last round of
discussion of this set of changes[1].

[1] https://lkml.kernel.org/r/CAHk-=wj8BQbgJFLa+J0e=iT-1qpmCRTbPAJ8gd6MJQ=kbRPqyQ@mail.gmail.com
Link: https://lkml.kernel.org/r/20201120231441.29911-9-ebiederm@xmission.com


Signed-off-by: default avatarEric W. Biederman <ebiederm@xmission.com>
parent 120ce2b0
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -62,7 +62,7 @@ the fdtable structure -
   be held.

4. To look up the file structure given an fd, a reader
   must use either fcheck() or fcheck_files() APIs. These
   must use either fcheck() or files_lookup_fd_rcu() APIs. These
   take care of barrier requirements due to lock-free lookup.

   An example::
@@ -84,7 +84,7 @@ the fdtable structure -
   on ->f_count::

	rcu_read_lock();
	file = fcheck_files(files, fd);
	file = files_lookup_fd_rcu(files, fd);
	if (file) {
		if (atomic_long_inc_not_zero(&file->f_count))
			*fput_needed = 1;
@@ -104,7 +104,7 @@ the fdtable structure -
   lock-free, they must be installed using rcu_assign_pointer()
   API. If they are looked up lock-free, rcu_dereference()
   must be used. However it is advisable to use files_fdtable()
   and fcheck()/fcheck_files() which take care of these issues.
   and fcheck()/files_lookup_fd_rcu() which take care of these issues.

7. While updating, the fdtable pointer must be looked up while
   holding files->file_lock. If ->file_lock is dropped, then
+2 −2
Original line number Diff line number Diff line
@@ -814,7 +814,7 @@ static struct file *__fget_files(struct files_struct *files, unsigned int fd,

	rcu_read_lock();
loop:
	file = fcheck_files(files, fd);
	file = files_lookup_fd_rcu(files, fd);
	if (file) {
		/* File object ref couldn't be taken.
		 * dup2() atomicity guarantee is the reason
@@ -1127,7 +1127,7 @@ SYSCALL_DEFINE2(dup2, unsigned int, oldfd, unsigned int, newfd)
		int retval = oldfd;

		rcu_read_lock();
		if (!fcheck_files(files, oldfd))
		if (!files_lookup_fd_rcu(files, oldfd))
			retval = -EBADF;
		rcu_read_unlock();
		return retval;
+2 −2
Original line number Diff line number Diff line
@@ -90,7 +90,7 @@ static bool tid_fd_mode(struct task_struct *task, unsigned fd, fmode_t *mode)
		return false;

	rcu_read_lock();
	file = fcheck_files(files, fd);
	file = files_lookup_fd_rcu(files, fd);
	if (file)
		*mode = file->f_mode;
	rcu_read_unlock();
@@ -243,7 +243,7 @@ static int proc_readfd_common(struct file *file, struct dir_context *ctx,
		char name[10 + 1];
		unsigned int len;

		f = fcheck_files(files, fd);
		f = files_lookup_fd_rcu(files, fd);
		if (!f)
			continue;
		data.mode = f->f_mode;
+3 −4
Original line number Diff line number Diff line
@@ -98,10 +98,9 @@ static inline struct file *files_lookup_fd_locked(struct files_struct *files, un
	return files_lookup_fd_raw(files, fd);
}

static inline struct file *fcheck_files(struct files_struct *files, unsigned int fd)
static inline struct file *files_lookup_fd_rcu(struct files_struct *files, unsigned int fd)
{
	RCU_LOCKDEP_WARN(!rcu_read_lock_held() &&
			   !lockdep_is_held(&files->file_lock),
	RCU_LOCKDEP_WARN(!rcu_read_lock_held(),
			   "suspicious rcu_dereference_check() usage");
	return files_lookup_fd_raw(files, fd);
}
@@ -109,7 +108,7 @@ static inline struct file *fcheck_files(struct files_struct *files, unsigned int
/*
 * Check whether the specified fd has an open file.
 */
#define fcheck(fd)	fcheck_files(current->files, fd)
#define fcheck(fd)	files_lookup_fd_rcu(current->files, fd)

struct task_struct;

+1 −1
Original line number Diff line number Diff line
@@ -183,7 +183,7 @@ task_file_seq_get_next(struct bpf_iter_seq_task_file_info *info,
	for (; curr_fd < max_fds; curr_fd++) {
		struct file *f;

		f = fcheck_files(curr_files, curr_fd);
		f = files_lookup_fd_rcu(curr_files, curr_fd);
		if (!f)
			continue;
		if (!get_file_rcu(f))
Loading