xref: /third_party/NuttX/fs/vfs/fs_truncate64.c (revision beacf11b)
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
63static 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
100errout:
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
138int 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