diff options
Diffstat (limited to 'include/linux/fdtable.h')
-rw-r--r-- | include/linux/fdtable.h | 35 |
1 files changed, 21 insertions, 14 deletions
diff --git a/include/linux/fdtable.h b/include/linux/fdtable.h index 085197bd8812..70e8e21c0a30 100644 --- a/include/linux/fdtable.h +++ b/include/linux/fdtable.h | |||
@@ -59,29 +59,36 @@ struct files_struct { | |||
59 | struct file __rcu * fd_array[NR_OPEN_DEFAULT]; | 59 | struct file __rcu * fd_array[NR_OPEN_DEFAULT]; |
60 | }; | 60 | }; |
61 | 61 | ||
62 | #define rcu_dereference_check_fdtable(files, fdtfd) \ | ||
63 | (rcu_dereference_check((fdtfd), \ | ||
64 | lockdep_is_held(&(files)->file_lock) || \ | ||
65 | atomic_read(&(files)->count) == 1 || \ | ||
66 | rcu_my_thread_group_empty())) | ||
67 | |||
68 | #define files_fdtable(files) \ | ||
69 | (rcu_dereference_check_fdtable((files), (files)->fdt)) | ||
70 | |||
71 | struct file_operations; | 62 | struct file_operations; |
72 | struct vfsmount; | 63 | struct vfsmount; |
73 | struct dentry; | 64 | struct dentry; |
74 | 65 | ||
75 | extern void __init files_defer_init(void); | 66 | extern void __init files_defer_init(void); |
76 | 67 | ||
77 | static inline struct file * fcheck_files(struct files_struct *files, unsigned int fd) | 68 | #define rcu_dereference_check_fdtable(files, fdtfd) \ |
69 | rcu_dereference_check((fdtfd), lockdep_is_held(&(files)->file_lock)) | ||
70 | |||
71 | #define files_fdtable(files) \ | ||
72 | rcu_dereference_check_fdtable((files), (files)->fdt) | ||
73 | |||
74 | /* | ||
75 | * The caller must ensure that fd table isn't shared or hold rcu or file lock | ||
76 | */ | ||
77 | static inline struct file *__fcheck_files(struct files_struct *files, unsigned int fd) | ||
78 | { | 78 | { |
79 | struct file * file = NULL; | 79 | struct fdtable *fdt = rcu_dereference_raw(files->fdt); |
80 | struct fdtable *fdt = files_fdtable(files); | ||
81 | 80 | ||
82 | if (fd < fdt->max_fds) | 81 | if (fd < fdt->max_fds) |
83 | file = rcu_dereference_check_fdtable(files, fdt->fd[fd]); | 82 | return rcu_dereference_raw(fdt->fd[fd]); |
84 | return file; | 83 | return NULL; |
84 | } | ||
85 | |||
86 | static inline struct file *fcheck_files(struct files_struct *files, unsigned int fd) | ||
87 | { | ||
88 | rcu_lockdep_assert(rcu_read_lock_held() || | ||
89 | lockdep_is_held(&files->file_lock), | ||
90 | "suspicious rcu_dereference_check() usage"); | ||
91 | return __fcheck_files(files, fd); | ||
85 | } | 92 | } |
86 | 93 | ||
87 | /* | 94 | /* |