1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
29f3acc31SAl Viro /*
39f3acc31SAl Viro * descriptor table internals; you almost certainly want file.h instead.
49f3acc31SAl Viro */
59f3acc31SAl Viro
69f3acc31SAl Viro #ifndef __LINUX_FDTABLE_H
79f3acc31SAl Viro #define __LINUX_FDTABLE_H
89f3acc31SAl Viro
99f3acc31SAl Viro #include <linux/posix_types.h>
109f3acc31SAl Viro #include <linux/compiler.h>
119f3acc31SAl Viro #include <linux/spinlock.h>
129f3acc31SAl Viro #include <linux/rcupdate.h>
1356c30ba7SDan Williams #include <linux/nospec.h>
149f3acc31SAl Viro #include <linux/types.h>
1521e54459SIngo Molnar #include <linux/init.h>
162c666df8SPaul E. McKenney #include <linux/fs.h>
1721e54459SIngo Molnar
1860063497SArun Sharma #include <linux/atomic.h>
199f3acc31SAl Viro
209f3acc31SAl Viro /*
219f3acc31SAl Viro * The default fd array needs to be at least BITS_PER_LONG,
229f3acc31SAl Viro * as this is the granularity returned by copy_fdset().
239f3acc31SAl Viro */
249f3acc31SAl Viro #define NR_OPEN_DEFAULT BITS_PER_LONG
259f3acc31SAl Viro
269f3acc31SAl Viro struct fdtable {
279f3acc31SAl Viro unsigned int max_fds;
284d2deb40SArnd Bergmann struct file __rcu **fd; /* current fd array */
291fd36adcSDavid Howells unsigned long *close_on_exec;
301fd36adcSDavid Howells unsigned long *open_fds;
31f3f86e33SLinus Torvalds unsigned long *full_fds_bits;
329f3acc31SAl Viro struct rcu_head rcu;
339f3acc31SAl Viro };
349f3acc31SAl Viro
359f3acc31SAl Viro /*
369f3acc31SAl Viro * Open file table structure
379f3acc31SAl Viro */
389f3acc31SAl Viro struct files_struct {
399f3acc31SAl Viro /*
409f3acc31SAl Viro * read mostly part
419f3acc31SAl Viro */
429f3acc31SAl Viro atomic_t count;
438a81252bSEric Dumazet bool resize_in_progress;
448a81252bSEric Dumazet wait_queue_head_t resize_wait;
458a81252bSEric Dumazet
464d2deb40SArnd Bergmann struct fdtable __rcu *fdt;
479f3acc31SAl Viro struct fdtable fdtab;
489f3acc31SAl Viro /*
499f3acc31SAl Viro * written part on a separate cache line in SMP
509f3acc31SAl Viro */
519f3acc31SAl Viro spinlock_t file_lock ____cacheline_aligned_in_smp;
529b80a184SAlexey Dobriyan unsigned int next_fd;
531fd36adcSDavid Howells unsigned long close_on_exec_init[1];
541fd36adcSDavid Howells unsigned long open_fds_init[1];
55f3f86e33SLinus Torvalds unsigned long full_fds_bits_init[1];
564d2deb40SArnd Bergmann struct file __rcu * fd_array[NR_OPEN_DEFAULT];
579f3acc31SAl Viro };
589f3acc31SAl Viro
599f3acc31SAl Viro struct file_operations;
609f3acc31SAl Viro struct vfsmount;
619f3acc31SAl Viro struct dentry;
629f3acc31SAl Viro
63a8d4b834SOleg Nesterov #define rcu_dereference_check_fdtable(files, fdtfd) \
64a8d4b834SOleg Nesterov rcu_dereference_check((fdtfd), lockdep_is_held(&(files)->file_lock))
65a8d4b834SOleg Nesterov
66a8d4b834SOleg Nesterov #define files_fdtable(files) \
67a8d4b834SOleg Nesterov rcu_dereference_check_fdtable((files), (files)->fdt)
68a8d4b834SOleg Nesterov
69a8d4b834SOleg Nesterov /*
70a8d4b834SOleg Nesterov * The caller must ensure that fd table isn't shared or hold rcu or file lock
71a8d4b834SOleg Nesterov */
files_lookup_fd_raw(struct files_struct * files,unsigned int fd)72bebf684bSEric W. Biederman static inline struct file *files_lookup_fd_raw(struct files_struct *files, unsigned int fd)
739f3acc31SAl Viro {
74a8d4b834SOleg Nesterov struct fdtable *fdt = rcu_dereference_raw(files->fdt);
75253ca867SLinus Torvalds unsigned long mask = array_index_mask_nospec(fd, fdt->max_fds);
76253ca867SLinus Torvalds struct file *needs_masking;
779f3acc31SAl Viro
78253ca867SLinus Torvalds /*
79253ca867SLinus Torvalds * 'mask' is zero for an out-of-bounds fd, all ones for ok.
80253ca867SLinus Torvalds * 'fd&mask' is 'fd' for ok, or 0 for out of bounds.
81253ca867SLinus Torvalds *
82253ca867SLinus Torvalds * Accessing fdt->fd[0] is ok, but needs masking of the result.
83253ca867SLinus Torvalds */
84253ca867SLinus Torvalds needs_masking = rcu_dereference_raw(fdt->fd[fd&mask]);
85253ca867SLinus Torvalds return (struct file *)(mask & (unsigned long)needs_masking);
86a8d4b834SOleg Nesterov }
87a8d4b834SOleg Nesterov
files_lookup_fd_locked(struct files_struct * files,unsigned int fd)88120ce2b0SEric W. Biederman static inline struct file *files_lookup_fd_locked(struct files_struct *files, unsigned int fd)
89120ce2b0SEric W. Biederman {
90120ce2b0SEric W. Biederman RCU_LOCKDEP_WARN(!lockdep_is_held(&files->file_lock),
91120ce2b0SEric W. Biederman "suspicious rcu_dereference_check() usage");
92120ce2b0SEric W. Biederman return files_lookup_fd_raw(files, fd);
93120ce2b0SEric W. Biederman }
94120ce2b0SEric W. Biederman
close_on_exec(unsigned int fd,const struct files_struct * files)95f60d374dSAl Viro static inline bool close_on_exec(unsigned int fd, const struct files_struct *files)
96f60d374dSAl Viro {
97f60d374dSAl Viro return test_bit(fd, files_fdtable(files)->close_on_exec);
98f60d374dSAl Viro }
99f60d374dSAl Viro
1009f3acc31SAl Viro struct task_struct;
1019f3acc31SAl Viro
1029f3acc31SAl Viro void put_files_struct(struct files_struct *fs);
1031f702603SEric W. Biederman int unshare_files(void);
104*678379e1SAl Viro struct fd_range {
105*678379e1SAl Viro unsigned int from, to;
106*678379e1SAl Viro };
107*678379e1SAl Viro struct files_struct *dup_fd(struct files_struct *, struct fd_range *) __latent_entropy;
1086a6d27deSAl Viro void do_close_on_exec(struct files_struct *);
109c3c073f8SAl Viro int iterate_fd(struct files_struct *, unsigned,
110c3c073f8SAl Viro int (*)(const void *, struct file *, unsigned),
111c3c073f8SAl Viro const void *);
1129f3acc31SAl Viro
1138760c909SEric W. Biederman extern int close_fd(unsigned int fd);
114a88c955fSChristian Brauner extern struct file *file_close_fd(unsigned int fd);
115dcfadfa4SAl Viro
1169f3acc31SAl Viro extern struct kmem_cache *files_cachep;
1179f3acc31SAl Viro
1189f3acc31SAl Viro #endif /* __LINUX_FDTABLE_H */
119