• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /****************************************************************************
2  * fs/vfs/fs_truncate64.c
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) 2018 Gregory Nutt. All rights reserved.
8  *   Author: Gregory Nutt <gnutt@nuttx.org>
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  *
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in
18  *    the documentation and/or other materials provided with the
19  *    distribution.
20  * 3. Neither the name NuttX nor the names of its contributors may be
21  *    used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
31  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
32  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35  * POSSIBILITY OF SUCH DAMAGE.
36  *
37  ****************************************************************************/
38 
39 /****************************************************************************
40  * Included Files
41  ****************************************************************************/
42 
43 #include "vfs_config.h"
44 #include "sys/types.h"
45 #include "unistd.h"
46 #include "fcntl.h"
47 #include "sched.h"
48 #include "assert.h"
49 #include "errno.h"
50 
51 #include "vnode.h"
52 
53 /****************************************************************************
54  * Name: file_truncate
55  *
56  * Description:
57  *   Equivalent to the standard ftruncate() function except that is accepts
58  *   a struct file instance instead of a file descriptor and it does not set
59  *   the errno variable.
60  *
61  ****************************************************************************/
62 
file_truncate64(struct file * filep,off64_t length)63 static int file_truncate64(struct file *filep, off64_t length)
64 {
65   struct Vnode *vnode = NULL;
66   int err;
67 
68   /* Was this file opened for write access? */
69 
70   if (((unsigned int)(filep->f_oflags) & O_ACCMODE) == O_RDONLY)
71     {
72       err = -EACCES;
73       goto errout;
74     }
75 
76   /* Is this vnode a registered mountpoint? Does it support the
77    * truncate operations may be relevant to device drivers but only
78    * the mountpoint operations vtable contains a truncate method.
79    */
80 
81   vnode = filep->f_vnode;
82   if (!vnode || !vnode->vop || !vnode->vop->Truncate64)
83     {
84       err = -ENOSYS;
85       goto errout;
86     }
87 
88   /* Does the file system support the truncate method?  It should if it is
89    * a write-able file system.
90    */
91 
92   err = vnode->vop->Truncate64(vnode, length);
93   if (err < 0)
94     {
95       goto errout;
96     }
97 
98   return OK;
99 
100 errout:
101   set_errno(-err);
102   return VFS_ERROR;
103 }
104 
105 /****************************************************************************
106  * Name: ftruncate
107  *
108  * Description:
109  *   The ftruncate() function causes the regular file referenced by fd to
110  *   have a size of length bytes.
111  *
112  *   If the file previously was larger than length, the extra data is
113  *   discarded.  If it was previously shorter than length, it is unspecified
114  *   whether the file is changed or its size increased.  If the file is
115  *   extended, the extended area appears as if it were zero-filled.  If fd
116  *   references a shared memory object, ftruncate() sets the size of the
117  *   shared memory object to length. If the file is not a regular file or
118  *   a shared memory object, the result is unspecified.
119 
120  *   With ftruncate(), the file must be open for writing; for truncate(),
121  *   the process must have write permission for the file.
122  *
123  *   ftruncate() does not modify the file offset for any open file
124  *   descriptions associated with the file.
125  *
126  * Input Parameters:
127  *   fd     - A reference to an open, regular file or shared memory object
128  *            to be truncated.
129  *   length - The new length of the file or shared memory object.
130  *
131  * Returned Value:
132  * On success, 0.
133  * On error, -1 is returned, and errno is set appro-priately:
134  *
135  *
136  ****************************************************************************/
137 
ftruncate64(int fd,off64_t length)138 int ftruncate64(int fd, off64_t length)
139 {
140 #if CONFIG_NFILE_DESCRIPTORS > 0
141   struct file *filep = NULL;
142 #endif
143 
144   /* Did we get a valid file descriptor? */
145 
146 #if CONFIG_NFILE_DESCRIPTORS > 0
147   if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS)
148 #endif
149     {
150       set_errno(EBADF);
151       return VFS_ERROR;
152     }
153 
154 #if CONFIG_NFILE_DESCRIPTORS > 0
155   /* The descriptor is in the right range to be a file descriptor... write
156    * to the file.
157    */
158 
159   int ret = fs_getfilep(fd, &filep);
160   if (ret < 0)
161     {
162       /* The errno value has already been set */
163       return VFS_ERROR;
164     }
165 
166   if (filep->f_oflags & O_DIRECTORY)
167     {
168       set_errno(EBADF);
169       return VFS_ERROR;
170     }
171 
172   /* Perform the truncate operation using the file descriptor as an index */
173 
174   return file_truncate64(filep, length);
175 #endif
176 }
177