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
close_on_exec(unsigned int fd,const struct fdtable * fdt)359b80a184SAlexey Dobriyan static inline bool close_on_exec(unsigned int fd, const struct fdtable *fdt)
361dce27c5SDavid Howells {
371fd36adcSDavid Howells return test_bit(fd, fdt->close_on_exec);
381dce27c5SDavid Howells }
391dce27c5SDavid Howells
fd_is_open(unsigned int fd,const struct fdtable * fdt)409b80a184SAlexey Dobriyan static inline bool fd_is_open(unsigned int fd, const struct fdtable *fdt)
411dce27c5SDavid Howells {
421fd36adcSDavid Howells return test_bit(fd, fdt->open_fds);
431dce27c5SDavid Howells }
441dce27c5SDavid Howells
459f3acc31SAl Viro /*
469f3acc31SAl Viro * Open file table structure
479f3acc31SAl Viro */
489f3acc31SAl Viro struct files_struct {
499f3acc31SAl Viro /*
509f3acc31SAl Viro * read mostly part
519f3acc31SAl Viro */
529f3acc31SAl Viro atomic_t count;
538a81252bSEric Dumazet bool resize_in_progress;
548a81252bSEric Dumazet wait_queue_head_t resize_wait;
558a81252bSEric Dumazet
564d2deb40SArnd Bergmann struct fdtable __rcu *fdt;
579f3acc31SAl Viro struct fdtable fdtab;
589f3acc31SAl Viro /*
599f3acc31SAl Viro * written part on a separate cache line in SMP
609f3acc31SAl Viro */
619f3acc31SAl Viro spinlock_t file_lock ____cacheline_aligned_in_smp;
629b80a184SAlexey Dobriyan unsigned int next_fd;
631fd36adcSDavid Howells unsigned long close_on_exec_init[1];
641fd36adcSDavid Howells unsigned long open_fds_init[1];
65f3f86e33SLinus Torvalds unsigned long full_fds_bits_init[1];
664d2deb40SArnd Bergmann struct file __rcu * fd_array[NR_OPEN_DEFAULT];
679f3acc31SAl Viro };
689f3acc31SAl Viro
699f3acc31SAl Viro struct file_operations;
709f3acc31SAl Viro struct vfsmount;
719f3acc31SAl Viro struct dentry;
729f3acc31SAl Viro
73a8d4b834SOleg Nesterov #define rcu_dereference_check_fdtable(files, fdtfd) \
74a8d4b834SOleg Nesterov rcu_dereference_check((fdtfd), lockdep_is_held(&(files)->file_lock))
75a8d4b834SOleg Nesterov
76a8d4b834SOleg Nesterov #define files_fdtable(files) \
77a8d4b834SOleg Nesterov rcu_dereference_check_fdtable((files), (files)->fdt)
78a8d4b834SOleg Nesterov
79a8d4b834SOleg Nesterov /*
80a8d4b834SOleg Nesterov * The caller must ensure that fd table isn't shared or hold rcu or file lock
81a8d4b834SOleg Nesterov */
files_lookup_fd_raw(struct files_struct * files,unsigned int fd)82bebf684bSEric W. Biederman static inline struct file *files_lookup_fd_raw(struct files_struct *files, unsigned int fd)
839f3acc31SAl Viro {
84a8d4b834SOleg Nesterov struct fdtable *fdt = rcu_dereference_raw(files->fdt);
859f3acc31SAl Viro
8656c30ba7SDan Williams if (fd < fdt->max_fds) {
8756c30ba7SDan Williams fd = array_index_nospec(fd, fdt->max_fds);
88a8d4b834SOleg Nesterov return rcu_dereference_raw(fdt->fd[fd]);
8956c30ba7SDan Williams }
90a8d4b834SOleg Nesterov return NULL;
91a8d4b834SOleg Nesterov }
92a8d4b834SOleg Nesterov
files_lookup_fd_locked(struct files_struct * files,unsigned int fd)93120ce2b0SEric W. Biederman static inline struct file *files_lookup_fd_locked(struct files_struct *files, unsigned int fd)
94120ce2b0SEric W. Biederman {
95120ce2b0SEric W. Biederman RCU_LOCKDEP_WARN(!lockdep_is_held(&files->file_lock),
96120ce2b0SEric W. Biederman "suspicious rcu_dereference_check() usage");
97120ce2b0SEric W. Biederman return files_lookup_fd_raw(files, fd);
98120ce2b0SEric W. Biederman }
99120ce2b0SEric W. Biederman
files_lookup_fd_rcu(struct files_struct * files,unsigned int fd)100f36c2943SEric W. Biederman static inline struct file *files_lookup_fd_rcu(struct files_struct *files, unsigned int fd)
101a8d4b834SOleg Nesterov {
102f36c2943SEric W. Biederman RCU_LOCKDEP_WARN(!rcu_read_lock_held(),
103a8d4b834SOleg Nesterov "suspicious rcu_dereference_check() usage");
104bebf684bSEric W. Biederman return files_lookup_fd_raw(files, fd);
1059f3acc31SAl Viro }
1069f3acc31SAl Viro
lookup_fd_rcu(unsigned int fd)107460b4f81SEric W. Biederman static inline struct file *lookup_fd_rcu(unsigned int fd)
108460b4f81SEric W. Biederman {
109460b4f81SEric W. Biederman return files_lookup_fd_rcu(current->files, fd);
110460b4f81SEric W. Biederman }
1119f3acc31SAl Viro
1123a879fb3SEric W. Biederman struct file *task_lookup_fd_rcu(struct task_struct *task, unsigned int fd);
113e9a53aebSEric W. Biederman struct file *task_lookup_next_fd_rcu(struct task_struct *task, unsigned int *fd);
1143a879fb3SEric W. Biederman
1159f3acc31SAl Viro struct task_struct;
1169f3acc31SAl Viro
1179f3acc31SAl Viro void put_files_struct(struct files_struct *fs);
1181f702603SEric W. Biederman int unshare_files(void);
119*a8023f8bSAl Viro struct fd_range {
120*a8023f8bSAl Viro unsigned int from, to;
121*a8023f8bSAl Viro };
122*a8023f8bSAl Viro struct files_struct *dup_fd(struct files_struct *, struct fd_range *) __latent_entropy;
1236a6d27deSAl Viro void do_close_on_exec(struct files_struct *);
124c3c073f8SAl Viro int iterate_fd(struct files_struct *, unsigned,
125c3c073f8SAl Viro int (*)(const void *, struct file *, unsigned),
126c3c073f8SAl Viro const void *);
1279f3acc31SAl Viro
1288760c909SEric W. Biederman extern int close_fd(unsigned int fd);
12960997c3dSChristian Brauner extern int __close_range(unsigned int fd, unsigned int max_fd, unsigned int flags);
1306319194eSAl Viro extern struct file *close_fd_get_file(unsigned int fd);
131dcfadfa4SAl Viro
1329f3acc31SAl Viro extern struct kmem_cache *files_cachep;
1339f3acc31SAl Viro
1349f3acc31SAl Viro #endif /* __LINUX_FDTABLE_H */
135