fs.h revision 331756
1/*-
2 * Copyright (c) 2010 Isilon Systems, Inc.
3 * Copyright (c) 2010 iX Systems, Inc.
4 * Copyright (c) 2010 Panasas, Inc.
5 * Copyright (c) 2013-2017 Mellanox Technologies, Ltd.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice unmodified, this list of conditions, and the following
13 *    disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * $FreeBSD: stable/11/sys/compat/linuxkpi/common/include/linux/fs.h 331756 2018-03-30 02:04:46Z emaste $
30 */
31#ifndef	_LINUX_FS_H_
32#define	_LINUX_FS_H_
33
34#include <sys/cdefs.h>
35#include <sys/param.h>
36#include <sys/systm.h>
37#include <sys/conf.h>
38#include <sys/vnode.h>
39#include <sys/file.h>
40#include <sys/filedesc.h>
41#include <linux/types.h>
42#include <linux/wait.h>
43#include <linux/semaphore.h>
44#include <linux/spinlock.h>
45#include <linux/dcache.h>
46
47struct module;
48struct kiocb;
49struct iovec;
50struct dentry;
51struct page;
52struct file_lock;
53struct pipe_inode_info;
54struct vm_area_struct;
55struct poll_table_struct;
56struct files_struct;
57struct pfs_node;
58
59#define	inode	vnode
60#define	i_cdev	v_rdev
61#define	i_private v_data
62
63#define	S_IRUGO	(S_IRUSR | S_IRGRP | S_IROTH)
64#define	S_IWUGO	(S_IWUSR | S_IWGRP | S_IWOTH)
65
66
67typedef struct files_struct *fl_owner_t;
68
69struct file_operations;
70
71struct linux_file_wait_queue {
72	struct wait_queue wq;
73	struct wait_queue_head *wqh;
74	atomic_t state;
75#define	LINUX_FWQ_STATE_INIT 0
76#define	LINUX_FWQ_STATE_NOT_READY 1
77#define	LINUX_FWQ_STATE_QUEUED 2
78#define	LINUX_FWQ_STATE_READY 3
79#define	LINUX_FWQ_STATE_MAX 4
80};
81
82struct linux_file {
83	struct file	*_file;
84	const struct file_operations	*f_op;
85	void		*private_data;
86	int		f_flags;
87	int		f_mode;	/* Just starting mode. */
88	struct dentry	*f_dentry;
89	struct dentry	f_dentry_store;
90	struct selinfo	f_selinfo;
91	struct sigio	*f_sigio;
92	struct vnode	*f_vnode;
93#define	f_inode	f_vnode
94	volatile u_int	f_count;
95
96	/* anonymous shmem object */
97	vm_object_t	f_shmem;
98
99	/* kqfilter support */
100	int		f_kqflags;
101#define	LINUX_KQ_FLAG_HAS_READ (1 << 0)
102#define	LINUX_KQ_FLAG_HAS_WRITE (1 << 1)
103#define	LINUX_KQ_FLAG_NEED_READ (1 << 2)
104#define	LINUX_KQ_FLAG_NEED_WRITE (1 << 3)
105	/* protects f_selinfo.si_note */
106	spinlock_t	f_kqlock;
107	struct linux_file_wait_queue f_wait_queue;
108};
109
110#define	file		linux_file
111#define	fasync_struct	sigio *
112
113#define	fasync_helper(fd, filp, on, queue)				\
114({									\
115	if ((on))							\
116		*(queue) = &(filp)->f_sigio;				\
117	else								\
118		*(queue) = NULL;					\
119	0;								\
120})
121
122#define	kill_fasync(queue, sig, pollstat)				\
123do {									\
124	if (*(queue) != NULL)						\
125		pgsigio(*(queue), (sig), 0);				\
126} while (0)
127
128typedef int (*filldir_t)(void *, const char *, int, loff_t, u64, unsigned);
129
130struct file_operations {
131	struct module *owner;
132	ssize_t (*read)(struct file *, char __user *, size_t, loff_t *);
133	ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *);
134	unsigned int (*poll) (struct file *, struct poll_table_struct *);
135	long (*unlocked_ioctl)(struct file *, unsigned int, unsigned long);
136	long (*compat_ioctl)(struct file *, unsigned int, unsigned long);
137	int (*mmap)(struct file *, struct vm_area_struct *);
138	int (*open)(struct inode *, struct file *);
139	int (*release)(struct inode *, struct file *);
140	int (*fasync)(int, struct file *, int);
141
142/* Although not supported in FreeBSD, to align with Linux code
143 * we are adding llseek() only when it is mapped to no_llseek which returns
144 * an illegal seek error
145 */
146	loff_t (*llseek)(struct file *, loff_t, int);
147#if 0
148	/* We do not support these methods.  Don't permit them to compile. */
149	loff_t (*llseek)(struct file *, loff_t, int);
150	ssize_t (*aio_read)(struct kiocb *, const struct iovec *,
151	    unsigned long, loff_t);
152	ssize_t (*aio_write)(struct kiocb *, const struct iovec *,
153	    unsigned long, loff_t);
154	int (*readdir)(struct file *, void *, filldir_t);
155	int (*ioctl)(struct inode *, struct file *, unsigned int,
156	    unsigned long);
157	int (*flush)(struct file *, fl_owner_t id);
158	int (*fsync)(struct file *, struct dentry *, int datasync);
159	int (*aio_fsync)(struct kiocb *, int datasync);
160	int (*lock)(struct file *, int, struct file_lock *);
161	ssize_t (*sendpage)(struct file *, struct page *, int, size_t,
162	    loff_t *, int);
163	unsigned long (*get_unmapped_area)(struct file *, unsigned long,
164	    unsigned long, unsigned long, unsigned long);
165	int (*check_flags)(int);
166	int (*flock)(struct file *, int, struct file_lock *);
167	ssize_t (*splice_write)(struct pipe_inode_info *, struct file *,
168	    loff_t *, size_t, unsigned int);
169	ssize_t (*splice_read)(struct file *, loff_t *,
170	    struct pipe_inode_info *, size_t, unsigned int);
171	int (*setlease)(struct file *, long, struct file_lock **);
172#endif
173};
174#define	fops_get(fops)		(fops)
175#define	replace_fops(f, fops)	((f)->f_op = (fops))
176
177#define	FMODE_READ	FREAD
178#define	FMODE_WRITE	FWRITE
179#define	FMODE_EXEC	FEXEC
180
181int __register_chrdev(unsigned int major, unsigned int baseminor,
182    unsigned int count, const char *name,
183    const struct file_operations *fops);
184int __register_chrdev_p(unsigned int major, unsigned int baseminor,
185    unsigned int count, const char *name,
186    const struct file_operations *fops, uid_t uid,
187    gid_t gid, int mode);
188void __unregister_chrdev(unsigned int major, unsigned int baseminor,
189    unsigned int count, const char *name);
190
191static inline void
192unregister_chrdev(unsigned int major, const char *name)
193{
194
195	__unregister_chrdev(major, 0, 256, name);
196}
197
198static inline int
199register_chrdev(unsigned int major, const char *name,
200    const struct file_operations *fops)
201{
202
203	return (__register_chrdev(major, 0, 256, name, fops));
204}
205
206static inline int
207register_chrdev_p(unsigned int major, const char *name,
208    const struct file_operations *fops, uid_t uid, gid_t gid, int mode)
209{
210
211	return (__register_chrdev_p(major, 0, 256, name, fops, uid, gid, mode));
212}
213
214static inline int
215register_chrdev_region(dev_t dev, unsigned range, const char *name)
216{
217
218	return 0;
219}
220
221static inline void
222unregister_chrdev_region(dev_t dev, unsigned range)
223{
224
225	return;
226}
227
228static inline int
229alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count,
230			const char *name)
231{
232
233	return 0;
234}
235
236/* No current support for seek op in FreeBSD */
237static inline int
238nonseekable_open(struct inode *inode, struct file *filp)
239{
240	return 0;
241}
242
243extern unsigned int linux_iminor(struct inode *);
244#define	iminor(...) linux_iminor(__VA_ARGS__)
245
246static inline struct linux_file *
247get_file(struct linux_file *f)
248{
249
250	refcount_acquire(f->_file == NULL ? &f->f_count : &f->_file->f_count);
251	return (f);
252}
253
254static inline struct inode *
255igrab(struct inode *inode)
256{
257	int error;
258
259	error = vget(inode, 0, curthread);
260	if (error)
261		return (NULL);
262
263	return (inode);
264}
265
266static inline void
267iput(struct inode *inode)
268{
269
270	vrele(inode);
271}
272
273static inline loff_t
274no_llseek(struct file *file, loff_t offset, int whence)
275{
276
277	return (-ESPIPE);
278}
279
280static inline loff_t
281noop_llseek(struct linux_file *file, loff_t offset, int whence)
282{
283
284	return (file->_file->f_offset);
285}
286
287static inline struct vnode *
288file_inode(const struct linux_file *file)
289{
290
291	return (file->f_vnode);
292}
293
294static inline int
295call_mmap(struct linux_file *file, struct vm_area_struct *vma)
296{
297
298	return (file->f_op->mmap(file, vma));
299}
300
301/* Shared memory support */
302unsigned long linux_invalidate_mapping_pages(vm_object_t, pgoff_t, pgoff_t);
303struct page *linux_shmem_read_mapping_page_gfp(vm_object_t, int, gfp_t);
304struct linux_file *linux_shmem_file_setup(const char *, loff_t, unsigned long);
305void linux_shmem_truncate_range(vm_object_t, loff_t, loff_t);
306
307#define	invalidate_mapping_pages(...) \
308  linux_invalidate_mapping_pages(__VA_ARGS__)
309
310#define	shmem_read_mapping_page(...) \
311  linux_shmem_read_mapping_page_gfp(__VA_ARGS__, 0)
312
313#define	shmem_read_mapping_page_gfp(...) \
314  linux_shmem_read_mapping_page_gfp(__VA_ARGS__)
315
316#define	shmem_file_setup(...) \
317  linux_shmem_file_setup(__VA_ARGS__)
318
319#define	shmem_truncate_range(...) \
320  linux_shmem_truncate_range(__VA_ARGS__)
321
322#endif /* _LINUX_FS_H_ */
323