file.h revision 289624
1/* $FreeBSD: head/sys/ofed/include/linux/file.h 289624 2015-10-20 11:40:04Z hselasky $ */
2/*-
3 * Copyright (c) 2010 Isilon Systems, Inc.
4 * Copyright (c) 2010 iX Systems, Inc.
5 * Copyright (c) 2010 Panasas, Inc.
6 * Copyright (c) 2013 Mellanox Technologies, Ltd.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice unmodified, this list of conditions, and the following
14 *    disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30#ifndef	_LINUX_FILE_H_
31#define	_LINUX_FILE_H_
32
33#include <sys/param.h>
34#include <sys/file.h>
35#include <sys/filedesc.h>
36#include <sys/refcount.h>
37#include <sys/capsicum.h>
38#include <sys/proc.h>
39
40#include <linux/fs.h>
41
42struct linux_file;
43
44#undef file
45
46extern struct fileops linuxfileops;
47
48static inline struct linux_file *
49linux_fget(unsigned int fd)
50{
51	cap_rights_t rights;
52	struct file *file;
53
54	if (fget_unlocked(curthread->td_proc->p_fd, fd,
55	    cap_rights_init(&rights), &file, NULL) != 0) {
56		return (NULL);
57	}
58	return (struct linux_file *)file->f_data;
59}
60
61static inline void
62fput(struct linux_file *filp)
63{
64	if (filp->_file == NULL) {
65		kfree(filp);
66		return;
67	}
68	if (refcount_release(&filp->_file->f_count)) {
69		_fdrop(filp->_file, curthread);
70		kfree(filp);
71	}
72}
73
74static inline void
75put_unused_fd(unsigned int fd)
76{
77	cap_rights_t rights;
78	struct file *file;
79
80	if (fget_unlocked(curthread->td_proc->p_fd, fd,
81	    cap_rights_init(&rights), &file, NULL) != 0) {
82		return;
83	}
84	/*
85	 * NOTE: We should only get here when the "fd" has not been
86	 * installed, so no need to free the associated Linux file
87	 * structure.
88	 */
89	fdclose(curthread, file, fd);
90
91	/* drop extra reference */
92	fdrop(file, curthread);
93}
94
95static inline void
96fd_install(unsigned int fd, struct linux_file *filp)
97{
98	cap_rights_t rights;
99	struct file *file;
100
101	if (fget_unlocked(curthread->td_proc->p_fd, fd,
102	    cap_rights_init(&rights), &file, NULL) != 0) {
103		file = NULL;
104	}
105	filp->_file = file;
106	finit(file, filp->f_mode, DTYPE_DEV, filp, &linuxfileops);
107
108	/* drop the extra reference */
109	fput(filp);
110}
111
112static inline int
113get_unused_fd(void)
114{
115	struct file *file;
116	int error;
117	int fd;
118
119	error = falloc(curthread, &file, &fd, 0);
120	if (error)
121		return -error;
122	/* drop the extra reference */
123	fdrop(file, curthread);
124	return fd;
125}
126
127static inline struct linux_file *
128alloc_file(int mode, const struct file_operations *fops)
129{
130	struct linux_file *filp;
131
132	filp = kzalloc(sizeof(*filp), GFP_KERNEL);
133	if (filp == NULL)
134		return (NULL);
135	filp->f_op = fops;
136	filp->f_mode = mode;
137
138	return filp;
139}
140
141struct fd {
142	struct linux_file *linux_file;
143};
144
145static inline void fdput(struct fd fd)
146{
147	fput(fd.linux_file);
148}
149
150static inline struct fd fdget(unsigned int fd)
151{
152	struct linux_file *f = linux_fget(fd);
153	return (struct fd){f};
154}
155
156#define	file	linux_file
157#define	fget	linux_fget
158
159#endif	/* _LINUX_FILE_H_ */
160