• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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