1 /**************************************************************************** 2 * include/fs/file.h 3 * 4 * Copyright (c) 2023 Huawei Device Co., Ltd. All rights reserved. 5 * Based on NuttX originally written by Gregory Nutt 6 * 7 * Copyright (C) 2007-2009, 2011-2013, 2015-2018 Gregory Nutt. All rights 8 * reserved. 9 * Author: Gregory Nutt <gnutt@nuttx.org> 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in 19 * the documentation and/or other materials provided with the 20 * distribution. 21 * 3. Neither the name NuttX nor the names of its contributors may be 22 * used to endorse or promote products derived from this software 23 * without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 28 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 29 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 31 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 32 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 33 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 35 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 * 38 ****************************************************************************/ 39 40 #ifndef __INCLUDE_FS_FILE_H 41 #define __INCLUDE_FS_FILE_H 42 43 /**************************************************************************** 44 * Included Files 45 ****************************************************************************/ 46 47 #include "vfs_config.h" 48 49 #include "sys/types.h" 50 #include "sys/stat.h" 51 #include "semaphore.h" 52 #include "poll.h" 53 #include "los_vm_map.h" 54 #include "los_atomic.h" 55 56 #ifdef __cplusplus 57 #if __cplusplus 58 extern "C" { 59 #endif /* __cplusplus */ 60 #endif /* __cplusplus */ 61 62 #ifndef VFS_ERROR 63 #define VFS_ERROR -1 64 #endif 65 66 #ifndef OK 67 #define OK 0 68 #endif 69 70 /* minimal fd allocated for file */ 71 #define FILE_START_FD 3 72 73 struct Vnode; 74 75 /* file mapped in VMM pages */ 76 struct page_mapping { 77 LOS_DL_LIST page_list; /* all pages */ 78 SPIN_LOCK_S list_lock; /* lock protecting it */ 79 LosMux mux_lock; /* mutex lock */ 80 unsigned long nrpages; /* number of total pages */ 81 unsigned long flags; 82 Atomic ref; /* reference counting */ 83 struct Vnode *host; /* owner of this mapping */ 84 }; 85 86 /* This is the underlying representation of an open file. A file 87 * descriptor is an index into an array of such types. The type associates 88 * the file descriptor to the file state and to a set of vnode operations. 89 */ 90 91 struct file 92 { 93 unsigned int f_magicnum; /* file magic number. -- to be deleted */ 94 int f_oflags; /* Open mode flags */ 95 struct Vnode *f_vnode; /* Driver interface */ 96 loff_t f_pos; /* File position */ 97 unsigned long f_refcount; /* reference count */ 98 char *f_path; /* File fullpath */ 99 void *f_priv; /* Per file driver private data */ 100 const char *f_relpath; /* realpath. -- to be deleted */ 101 struct page_mapping *f_mapping; /* mapping file to memory */ 102 void *f_dir; /* DIR struct for iterate the directory if open a directory */ 103 const struct file_operations_vfs *ops; 104 int fd; 105 }; 106 107 /* This defines a list of files indexed by the file descriptor */ 108 109 #if CONFIG_NFILE_DESCRIPTORS > 0 110 struct filelist 111 { 112 sem_t fl_sem; /* Manage access to the file list */ 113 struct file fl_files[CONFIG_NFILE_DESCRIPTORS]; 114 }; 115 116 extern struct filelist tg_filelist; 117 #endif 118 119 /* This structure is provided by devices when they are registered with the 120 * system. It is used to call back to perform device specific operations. 121 */ 122 123 struct file_operations_vfs 124 { 125 /* The device driver open method differs from the mountpoint open method */ 126 127 int (*open)(struct file *filep); 128 129 /* The following methods must be identical in signature and position because 130 * the struct file_operations and struct mountp_operations are treated like 131 * unions. 132 */ 133 134 int (*close)(struct file *filep); 135 ssize_t (*read)(struct file *filep, char *buffer, size_t buflen); 136 ssize_t (*write)(struct file *filep, const char *buffer, size_t buflen); 137 off_t (*seek)(struct file *filep, off_t offset, int whence); 138 int (*ioctl)(struct file *filep, int cmd, unsigned long arg); 139 int (*mmap)(struct file* filep, struct VmMapRegion *region); 140 /* The two structures need not be common after this point */ 141 142 int (*poll)(struct file *filep, poll_table *fds); 143 int (*stat)(struct file *filep, struct stat* st); 144 int (*fallocate)(struct file* filep, int mode, off_t offset, off_t len); 145 int (*fallocate64)(struct file *filep, int mode, off64_t offset, off64_t len); 146 int (*fsync)(struct file *filep); 147 ssize_t (*readpage)(struct file *filep, char *buffer, size_t buflen); 148 int (*unlink)(struct Vnode *vnode); 149 }; 150 151 void file_hold(struct file *filep); 152 void file_release(struct file *filep); 153 154 /**************************************************************************** 155 * Name: files_initlist 156 * 157 * Description: 158 * Initializes the list of files for a new task 159 * 160 ****************************************************************************/ 161 162 #if CONFIG_NFILE_DESCRIPTORS > 0 163 void files_initlist(struct filelist *list); 164 #endif 165 166 /**************************************************************************** 167 * Name: files_releaselist 168 * 169 * Description: 170 * Release a reference to the file list 171 * 172 ****************************************************************************/ 173 174 #if CONFIG_NFILE_DESCRIPTORS > 0 175 void files_releaselist(struct filelist *list); 176 #endif 177 178 /**************************************************************************** 179 * Name: file_dup2 180 * 181 * Description: 182 * Assign an vnode to a specific files structure. This is the heart of 183 * dup2. 184 * 185 * Equivalent to the non-standard fs_dupfd2() function except that it 186 * accepts struct file instances instead of file descriptors and it does 187 * not set the errno variable. 188 * 189 * Returned Value: 190 * Zero (OK) is returned on success; a negated errno value is return on 191 * any failure. 192 * 193 ****************************************************************************/ 194 195 #if CONFIG_NFILE_DESCRIPTORS > 0 196 int file_dup2(struct file *filep1, struct file *filep2); 197 #endif 198 199 /**************************************************************************** 200 * Name: fs_dupfd OR dup 201 * 202 * Description: 203 * Clone a file descriptor 'fd' to an arbitrary descriptor number (any value 204 * greater than or equal to 'minfd'). If socket descriptors are 205 * implemented, then this is called by dup() for the case of file 206 * descriptors. If socket descriptors are not implemented, then this 207 * function IS dup(). 208 * 209 * This alternative naming is used when dup could operate on both file and 210 * socket descriptors to avoid drawing unused socket support into the link. 211 * 212 * Returned Value: 213 * fs_dupfd is sometimes an OS internal function and sometimes is a direct 214 * substitute for dup(). So it must return an errno value as though it 215 * were dup(). 216 * 217 ****************************************************************************/ 218 219 #if CONFIG_NFILE_DESCRIPTORS > 0 220 int fs_dupfd(int fd, int minfd); 221 #endif 222 223 /**************************************************************************** 224 * Name: file_dup 225 * 226 * Description: 227 * Equivalent to the non-standard fs_dupfd() function except that it 228 * accepts a struct file instance instead of a file descriptor and does 229 * not set the errno variable. 230 * 231 * Returned Value: 232 * Zero (OK) is returned on success; a negated errno value is returned on 233 * any failure. 234 * 235 ****************************************************************************/ 236 237 int file_dup(struct file *filep, int minfd); 238 239 /**************************************************************************** 240 * Name: fs_dupfd2 OR dup2 241 * 242 * Description: 243 * Clone a file descriptor to a specific descriptor number. If socket 244 * descriptors are implemented, then this is called by dup2() for the 245 * case of file descriptors. If socket descriptors are not implemented, 246 * then this function IS dup2(). 247 * 248 * This alternative naming is used when dup2 could operate on both file and 249 * socket descriptors to avoid drawing unused socket support into the link. 250 * 251 * Returned Value: 252 * fs_dupfd2 is sometimes an OS internal function and sometimes is a direct 253 * substitute for dup2(). So it must return an errno value as though it 254 * were dup2(). 255 * 256 ****************************************************************************/ 257 258 #if CONFIG_NFILE_DESCRIPTORS > 0 259 int fs_dupfd2(int fd1, int fd2); 260 #endif 261 262 /**************************************************************************** 263 * Name: fs_ioctl 264 * 265 * Description: 266 * Perform device specific operations. 267 * 268 * Input Parameters: 269 * fd File/socket descriptor of device 270 * req The ioctl command 271 * arg The argument of the ioctl cmd 272 * 273 * Returned Value: 274 * >=0 on success (positive non-zero values are cmd-specific) 275 * -1 on failure with errno set properly: 276 * 277 * EBADF 278 * 'fd' is not a valid descriptor. 279 * EFAULT 280 * 'arg' references an inaccessible memory area. 281 * EINVAL 282 * 'cmd' or 'arg' is not valid. 283 * ENOTTY 284 * 'fd' is not associated with a character special device. 285 * ENOTTY 286 * The specified request does not apply to the kind of object that the 287 * descriptor 'fd' references. 288 * 289 ****************************************************************************/ 290 #ifdef CONFIG_LIBC_IOCTL_VARIADIC 291 int fs_ioctl(int fd, int req, unsigned long arg); 292 #endif 293 294 /**************************************************************************** 295 * Name: lib_sendfile 296 * 297 * Description: 298 * Transfer a file 299 * 300 ****************************************************************************/ 301 302 #ifdef CONFIG_NET_SENDFILE 303 ssize_t lib_sendfile(int outfd, int infd, off_t *offset, size_t count); 304 #endif 305 306 /**************************************************************************** 307 * Name: fs_getfilep 308 * 309 * Description: 310 * Given a file descriptor, return the corresponding instance of struct 311 * file. NOTE that this function will currently fail if it is provided 312 * with a socket descriptor. 313 * 314 * Input Parameters: 315 * fd - The file descriptor 316 * filep - The location to return the struct file instance 317 * 318 * Returned Value: 319 * Zero (OK) is returned on success; a negated errno value is returned on 320 * any failure. 321 * 322 ****************************************************************************/ 323 324 #if CONFIG_NFILE_DESCRIPTORS > 0 325 int fs_getfilep(int fd, struct file **filep); 326 #endif 327 328 /**************************************************************************** 329 * Name: file_read 330 * 331 * Description: 332 * file_read() is an internal OS interface. It is functionally similar to 333 * the standard read() interface except: 334 * 335 * - It does not modify the errno variable, 336 * - It is not a cancellation point, 337 * - It does not handle socket descriptors, and 338 * - It accepts a file structure instance instead of file descriptor. 339 * 340 * Input Parameters: 341 * filep - File structure instance 342 * buf - User-provided to save the data 343 * nbytes - The maximum size of the user-provided buffer 344 * 345 * Returned Value: 346 * The positive non-zero number of bytes read on success, 0 on if an 347 * end-of-file condition, or a negated errno value on any failure. 348 * 349 ****************************************************************************/ 350 351 #if CONFIG_NFILE_DESCRIPTORS > 0 352 ssize_t file_read(struct file *filep, void *buf, size_t nbytes); 353 #endif 354 355 /**************************************************************************** 356 * Name: file_write 357 * 358 * Description: 359 * Equivalent to the standard write() function except that is accepts a 360 * struct file instance instead of a file descriptor. Currently used 361 * only by aio_write(); 362 * 363 ****************************************************************************/ 364 365 #if CONFIG_NFILE_DESCRIPTORS > 0 366 ssize_t file_write(struct file *filep, const void *buf, size_t nbytes); 367 #endif 368 369 /**************************************************************************** 370 * Name: file_pread 371 * 372 * Description: 373 * Equivalent to the standard pread function except that is accepts a 374 * struct file instance instead of a file descriptor. Currently used 375 * only by aio_read(); 376 * 377 ****************************************************************************/ 378 379 #if CONFIG_NFILE_DESCRIPTORS > 0 380 ssize_t file_pread(struct file *filep, void *buf, size_t nbytes, 381 off_t offset); 382 #endif 383 384 /**************************************************************************** 385 * Name: file_pwrite 386 * 387 * Description: 388 * Equivalent to the standard pwrite function except that is accepts a 389 * struct file instance instead of a file descriptor. Currently used 390 * only by aio_write(); 391 * 392 ****************************************************************************/ 393 394 #if CONFIG_NFILE_DESCRIPTORS > 0 395 ssize_t file_pwrite(struct file *filep, const void *buf, 396 size_t nbytes, off_t offset); 397 #endif 398 399 /**************************************************************************** 400 * Name: file_seek 401 * 402 * Description: 403 * Equivalent to the standard lseek() function except that is accepts a 404 * struct file instance instead of a file descriptor. Currently used 405 * only by net_sendfile() 406 * 407 ****************************************************************************/ 408 409 #if CONFIG_NFILE_DESCRIPTORS > 0 410 off_t file_seek(struct file *filep, off_t offset, int whence); 411 #endif 412 413 /**************************************************************************** 414 * Name: file_fsync 415 * 416 * Description: 417 * Equivalent to the standard fsync() function except that is accepts a 418 * struct file instance instead of a file descriptor and it does not set 419 * the errno variable. 420 * 421 ****************************************************************************/ 422 423 #if CONFIG_NFILE_DESCRIPTORS > 0 424 int file_fsync(struct file *filep); 425 #endif 426 427 /**************************************************************************** 428 * Name: file_vfcntl 429 * 430 * Description: 431 * Similar to the standard vfcntl function except that is accepts a struct 432 * struct file instance instead of a file descriptor. 433 * 434 * Input Parameters: 435 * filep - Instance for struct file for the opened file. 436 * cmd - Indentifies the operation to be performed. 437 * ap - Variable argument following the command. 438 * 439 * Returned Value: 440 * The nature of the return value depends on the command. Non-negative 441 * values indicate success. Failures are reported as negated errno 442 * values. 443 * 444 ****************************************************************************/ 445 446 #if CONFIG_NFILE_DESCRIPTORS > 0 447 int file_vfcntl(struct file *filep, int cmd, va_list ap); 448 #endif 449 450 /**************************************************************************** 451 * Name: file_seek64 452 * 453 * Description: 454 * Equivalent to the standard lseek64() function except that is accepts a 455 * struct file instance instead of a file descriptor. Currently used 456 * only by net_sendfile() 457 * 458 ****************************************************************************/ 459 460 #if CONFIG_NFILE_DESCRIPTORS > 0 461 off64_t file_seek64(struct file *filep, off64_t offset, int whence); 462 #endif 463 464 /**************************************************************************** 465 * Name: files_allocate 466 * 467 * Description: 468 * Allocate a struct files instance and associate it with an vnode instance. 469 * Returns the file descriptor pointer. 470 * 471 ****************************************************************************/ 472 473 struct file *files_allocate(const struct Vnode *vnode_ptr, int oflags, off_t pos, const void *priv, int minfd); 474 475 /**************************************************************************** 476 * Name: files_close 477 * 478 * Description: 479 * Close an vnode (if open) 480 * 481 * Assumuptions: 482 * Caller holds the list semaphore because the file descriptor will be freed. 483 * 484 ****************************************************************************/ 485 486 int files_close(int fd); 487 488 /**************************************************************************** 489 * Name: files_release 490 * 491 * Assumuptions: 492 * Similar to files_close(). Called only from open() logic on error 493 * conditions. 494 * 495 ****************************************************************************/ 496 497 void files_release(int fd); 498 499 /**************************************************************************** 500 * Name: files_initialize 501 * 502 * Description: 503 * This is called from the FS initialization logic to configure the files. 504 * 505 ****************************************************************************/ 506 507 void WEAK files_initialize(void); 508 509 int vfs_normalize_path(const char *directory, const char *filename, char **pathname); 510 int vfs_normalize_pathat(int fd, const char *filename, char **pathname); 511 512 struct filelist *sched_getfiles(void); 513 514 /* fs/fs_sendfile.c *************************************************/ 515 /**************************************************************************** 516 * Name: sendfile 517 * 518 * Description: 519 * Copy data between one file descriptor and another. 520 * 521 ****************************************************************************/ 522 ssize_t sendfile(int outfd, int infd, off_t *offset, size_t count); 523 524 /** 525 * @ingroup fs 526 * @brief get the path by a given file fd. 527 * 528 * @par Description: 529 * The function is used for getting the path by a given file fd. 530 * 531 * @attention 532 * <ul> 533 * <li>Only support file fd, not any dir fd.</li> 534 * </ul> 535 * 536 * @param fd [IN] Type #int file fd. 537 * @param path [IN] Type #char ** address of the location to return the path reference. 538 * 539 * @retval #0 get path success 540 * @retval #~0 get path failed 541 * 542 * @par Dependency: 543 * <ul><li>fs.h: the header file that contains the API declaration.</li></ul> 544 * @see 545 * 546 * @since 2020-1-8 547 */ 548 549 int get_path_from_fd(int fd, char **path); 550 551 bool get_bit(int i); 552 553 int AllocProcessFd(void); 554 555 int AllocLowestProcessFd(int minFd); 556 557 int AllocSpecifiedProcessFd(int procFd); 558 559 int AllocAndAssocProcessFd(int sysFd, int minFd); 560 561 int AllocAndAssocSystemFd(int procFd, int minFd); 562 563 void AssociateSystemFd(int procFd, int sysFd); 564 565 int DisassociateProcessFd(int procFd); 566 567 int GetAssociatedSystemFd(int procFd); 568 569 int CheckProcessFd(int procFd); 570 571 void FreeProcessFd(int procFd); 572 573 int CopyFdToProc(int fd, unsigned int targetPid); 574 575 int CloseProcFd(int fd, unsigned int targetPid); 576 577 void lsfd(void); 578 579 void set_sd_sync_fn(int (*sync_fn)(int)); 580 581 struct Vnode *files_get_openfile(int fd); 582 583 void poll_wait(struct file *filp, wait_queue_head_t *wait_address, poll_table *p); 584 585 int follow_symlink(int dirfd, const char *path, struct Vnode **vnode, char **fullpath); 586 #ifdef __cplusplus 587 #if __cplusplus 588 } 589 #endif /* __cplusplus */ 590 #endif /* __cplusplus */ 591 #endif /* __INCLUDE_FS_FILE_H */ 592