xref: /openbmc/linux/include/linux/fdtable.h (revision fac59652993f075d57860769c99045b3ca18780d)
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