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-2018 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$ 30 */ 31 #ifndef _LINUXKPI_LINUX_FS_H_ 32 #define _LINUXKPI_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 #include <linux/capability.h> 47 #include <linux/wait_bit.h> 48 #include <linux/kernel.h> 49 #include <linux/mutex.h> 50 51 struct module; 52 struct kiocb; 53 struct iovec; 54 struct dentry; 55 struct page; 56 struct file_lock; 57 struct pipe_inode_info; 58 struct vm_area_struct; 59 struct poll_table_struct; 60 struct files_struct; 61 struct pfs_node; 62 struct linux_cdev; 63 64 #define inode vnode 65 #define i_cdev v_rdev 66 #define i_private v_data 67 68 #define S_IRUGO (S_IRUSR | S_IRGRP | S_IROTH) 69 #define S_IWUGO (S_IWUSR | S_IWGRP | S_IWOTH) 70 71 typedef struct files_struct *fl_owner_t; 72 73 struct file_operations; 74 75 struct linux_file_wait_queue { 76 struct wait_queue wq; 77 struct wait_queue_head *wqh; 78 atomic_t state; 79 #define LINUX_FWQ_STATE_INIT 0 80 #define LINUX_FWQ_STATE_NOT_READY 1 81 #define LINUX_FWQ_STATE_QUEUED 2 82 #define LINUX_FWQ_STATE_READY 3 83 #define LINUX_FWQ_STATE_MAX 4 84 }; 85 86 struct linux_file { 87 struct file *_file; 88 const struct file_operations *f_op; 89 void *private_data; 90 int f_flags; 91 int f_mode; /* Just starting mode. */ 92 struct dentry *f_dentry; 93 struct dentry f_dentry_store; 94 struct selinfo f_selinfo; 95 struct sigio *f_sigio; 96 struct vnode *f_vnode; 97 #define f_inode f_vnode 98 volatile u_int f_count; 99 100 /* anonymous shmem object */ 101 vm_object_t f_shmem; 102 103 /* kqfilter support */ 104 int f_kqflags; 105 #define LINUX_KQ_FLAG_HAS_READ (1 << 0) 106 #define LINUX_KQ_FLAG_HAS_WRITE (1 << 1) 107 #define LINUX_KQ_FLAG_NEED_READ (1 << 2) 108 #define LINUX_KQ_FLAG_NEED_WRITE (1 << 3) 109 /* protects f_selinfo.si_note */ 110 spinlock_t f_kqlock; 111 struct linux_file_wait_queue f_wait_queue; 112 113 /* pointer to associated character device, if any */ 114 struct linux_cdev *f_cdev; 115 116 struct rcu_head rcu; 117 }; 118 119 #define file linux_file 120 #define fasync_struct sigio * 121 122 #define fasync_helper(fd, filp, on, queue) \ 123 ({ \ 124 if ((on)) \ 125 *(queue) = &(filp)->f_sigio; \ 126 else \ 127 *(queue) = NULL; \ 128 0; \ 129 }) 130 131 #define kill_fasync(queue, sig, pollstat) \ 132 do { \ 133 if (*(queue) != NULL) \ 134 pgsigio(*(queue), (sig), 0); \ 135 } while (0) 136 137 typedef int (*filldir_t)(void *, const char *, int, off_t, u64, unsigned); 138 139 struct file_operations { 140 struct module *owner; 141 ssize_t (*read)(struct linux_file *, char __user *, size_t, off_t *); 142 ssize_t (*write)(struct linux_file *, const char __user *, size_t, off_t *); 143 unsigned int (*poll) (struct linux_file *, struct poll_table_struct *); 144 long (*unlocked_ioctl)(struct linux_file *, unsigned int, unsigned long); 145 long (*compat_ioctl)(struct linux_file *, unsigned int, unsigned long); 146 int (*mmap)(struct linux_file *, struct vm_area_struct *); 147 int (*open)(struct inode *, struct file *); 148 int (*release)(struct inode *, struct linux_file *); 149 int (*fasync)(int, struct linux_file *, int); 150 151 /* Although not supported in FreeBSD, to align with Linux code 152 * we are adding llseek() only when it is mapped to no_llseek which returns 153 * an illegal seek error 154 */ 155 off_t (*llseek)(struct linux_file *, off_t, int); 156 #if 0 157 /* We do not support these methods. Don't permit them to compile. */ 158 loff_t (*llseek)(struct file *, loff_t, int); 159 ssize_t (*aio_read)(struct kiocb *, const struct iovec *, 160 unsigned long, loff_t); 161 ssize_t (*aio_write)(struct kiocb *, const struct iovec *, 162 unsigned long, loff_t); 163 int (*readdir)(struct file *, void *, filldir_t); 164 int (*ioctl)(struct inode *, struct file *, unsigned int, 165 unsigned long); 166 int (*flush)(struct file *, fl_owner_t id); 167 int (*fsync)(struct file *, struct dentry *, int datasync); 168 int (*aio_fsync)(struct kiocb *, int datasync); 169 int (*lock)(struct file *, int, struct file_lock *); 170 ssize_t (*sendpage)(struct file *, struct page *, int, size_t, 171 loff_t *, int); 172 unsigned long (*get_unmapped_area)(struct file *, unsigned long, 173 unsigned long, unsigned long, unsigned long); 174 int (*check_flags)(int); 175 int (*flock)(struct file *, int, struct file_lock *); 176 ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, 177 loff_t *, size_t, unsigned int); 178 ssize_t (*splice_read)(struct file *, loff_t *, 179 struct pipe_inode_info *, size_t, unsigned int); 180 int (*setlease)(struct file *, long, struct file_lock **); 181 #endif 182 }; 183 #define fops_get(fops) (fops) 184 #define replace_fops(f, fops) ((f)->f_op = (fops)) 185 186 #define FMODE_READ FREAD 187 #define FMODE_WRITE FWRITE 188 #define FMODE_EXEC FEXEC 189 #define FMODE_UNSIGNED_OFFSET 0x2000 190 int __register_chrdev(unsigned int major, unsigned int baseminor, 191 unsigned int count, const char *name, 192 const struct file_operations *fops); 193 int __register_chrdev_p(unsigned int major, unsigned int baseminor, 194 unsigned int count, const char *name, 195 const struct file_operations *fops, uid_t uid, 196 gid_t gid, int mode); 197 void __unregister_chrdev(unsigned int major, unsigned int baseminor, 198 unsigned int count, const char *name); 199 200 static inline void 201 unregister_chrdev(unsigned int major, const char *name) 202 { 203 204 __unregister_chrdev(major, 0, 256, name); 205 } 206 207 static inline int 208 register_chrdev(unsigned int major, const char *name, 209 const struct file_operations *fops) 210 { 211 212 return (__register_chrdev(major, 0, 256, name, fops)); 213 } 214 215 static inline int 216 register_chrdev_p(unsigned int major, const char *name, 217 const struct file_operations *fops, uid_t uid, gid_t gid, int mode) 218 { 219 220 return (__register_chrdev_p(major, 0, 256, name, fops, uid, gid, mode)); 221 } 222 223 static inline int 224 register_chrdev_region(dev_t dev, unsigned range, const char *name) 225 { 226 227 return 0; 228 } 229 230 static inline void 231 unregister_chrdev_region(dev_t dev, unsigned range) 232 { 233 234 return; 235 } 236 237 static inline int 238 alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, 239 const char *name) 240 { 241 242 return 0; 243 } 244 245 /* No current support for seek op in FreeBSD */ 246 static inline int 247 nonseekable_open(struct inode *inode, struct file *filp) 248 { 249 return 0; 250 } 251 252 static inline int 253 simple_open(struct inode *inode, struct file *filp) 254 { 255 filp->private_data = inode->i_private; 256 return 0; 257 } 258 259 extern unsigned int linux_iminor(struct inode *); 260 #define iminor(...) linux_iminor(__VA_ARGS__) 261 262 static inline struct linux_file * 263 get_file(struct linux_file *f) 264 { 265 266 refcount_acquire(f->_file == NULL ? &f->f_count : &f->_file->f_count); 267 return (f); 268 } 269 270 static inline bool 271 get_file_rcu(struct linux_file *f) 272 { 273 return (refcount_acquire_if_not_zero( 274 f->_file == NULL ? &f->f_count : &f->_file->f_count)); 275 } 276 277 static inline struct inode * 278 igrab(struct inode *inode) 279 { 280 int error; 281 282 error = vget(inode, 0); 283 if (error) 284 return (NULL); 285 286 return (inode); 287 } 288 289 static inline void 290 iput(struct inode *inode) 291 { 292 293 vrele(inode); 294 } 295 296 static inline loff_t 297 no_llseek(struct file *file, loff_t offset, int whence) 298 { 299 300 return (-ESPIPE); 301 } 302 303 static inline loff_t 304 default_llseek(struct file *file, loff_t offset, int whence) 305 { 306 return (no_llseek(file, offset, whence)); 307 } 308 309 static inline loff_t 310 generic_file_llseek(struct file *file, loff_t offset, int whence) 311 { 312 return (no_llseek(file, offset, whence)); 313 } 314 315 static inline loff_t 316 noop_llseek(struct linux_file *file, loff_t offset, int whence) 317 { 318 319 return (file->_file->f_offset); 320 } 321 322 static inline struct vnode * 323 file_inode(const struct linux_file *file) 324 { 325 326 return (file->f_vnode); 327 } 328 329 static inline int 330 call_mmap(struct linux_file *file, struct vm_area_struct *vma) 331 { 332 333 return (file->f_op->mmap(file, vma)); 334 } 335 336 static inline void 337 i_size_write(struct inode *inode, loff_t i_size) 338 { 339 } 340 341 /* 342 * simple_read_from_buffer: copy data from kernel-space origin 343 * buffer into user-space destination buffer 344 * 345 * @dest: destination buffer 346 * @read_size: number of bytes to be transferred 347 * @ppos: starting transfer position pointer 348 * @orig: origin buffer 349 * @buf_size: size of destination and origin buffers 350 * 351 * Return value: 352 * On success, total bytes copied with *ppos incremented accordingly. 353 * On failure, negative value. 354 */ 355 static inline ssize_t 356 simple_read_from_buffer(void __user *dest, size_t read_size, loff_t *ppos, 357 void *orig, size_t buf_size) 358 { 359 void *read_pos = ((char *) orig) + *ppos; 360 size_t buf_remain = buf_size - *ppos; 361 ssize_t num_read; 362 363 if (buf_remain < 0 || buf_remain > buf_size) 364 return -EINVAL; 365 366 if (read_size > buf_remain) 367 read_size = buf_remain; 368 369 /* copy_to_user returns number of bytes NOT read */ 370 num_read = read_size - copy_to_user(dest, read_pos, read_size); 371 if (num_read == 0) 372 return -EFAULT; 373 *ppos += num_read; 374 375 return (num_read); 376 } 377 378 MALLOC_DECLARE(M_LSATTR); 379 380 #define DEFINE_SIMPLE_ATTRIBUTE(__fops, __get, __set, __fmt) \ 381 static inline int \ 382 __fops ## _open(struct inode *inode, struct file *filp) \ 383 { \ 384 return (simple_attr_open(inode, filp, __get, __set, __fmt)); \ 385 } \ 386 static const struct file_operations __fops = { \ 387 .owner = THIS_MODULE, \ 388 .open = __fops ## _open, \ 389 .release = simple_attr_release, \ 390 .read = simple_attr_read, \ 391 .write = simple_attr_write, \ 392 .llseek = no_llseek \ 393 } 394 395 int simple_attr_open(struct inode *inode, struct file *filp, 396 int (*get)(void *, uint64_t *), int (*set)(void *, uint64_t), 397 const char *fmt); 398 399 int simple_attr_release(struct inode *inode, struct file *filp); 400 401 ssize_t simple_attr_read(struct file *filp, char *buf, size_t read_size, loff_t *ppos); 402 403 ssize_t simple_attr_write(struct file *filp, const char *buf, size_t write_size, loff_t *ppos); 404 405 #endif /* _LINUXKPI_LINUX_FS_H_ */ 406