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