1/* 2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. 3 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without modification, 6 * are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, this list of 9 * conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 * of conditions and the following disclaimer in the documentation and/or other materials 13 * provided with the distribution. 14 * 15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used 16 * to endorse or promote products derived from this software without specific prior written 17 * permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32/**************************************************************************** 33 * Included Files 34 ****************************************************************************/ 35 36#include "assert.h" 37#include "errno.h" 38#include "fcntl.h" 39#include "fs/file.h" 40#include "sched.h" 41#include "sys/types.h" 42#include "unistd.h" 43#include "vfs_config.h" 44 45/**************************************************************************** 46 * Name: file_fallocate 47 ****************************************************************************/ 48 49ssize_t file_fallocate64(struct file *filep, int mode, off64_t offset, off64_t len) 50{ 51 int ret; 52 int err; 53 54 if (len <= 0) { 55 err = EINVAL; 56 goto errout; 57 } 58 59 /* Was this file opened for write access? */ 60 61 if (((unsigned int)(filep->f_oflags) & O_ACCMODE) == O_RDONLY) { 62 err = EACCES; 63 goto errout; 64 } 65 66 /* Is a driver registered? Does it support the fallocate method? */ 67 if (!filep->ops || !filep->ops->fallocate64) { 68 err = EBADF; 69 goto errout; 70 } 71 72 /* Yes, then let the driver perform the fallocate */ 73 74 ret = filep->ops->fallocate64(filep, mode, offset, len); 75 if (ret < 0) { 76 err = -ret; 77 goto errout; 78 } 79 80 return ret; 81 82errout: 83 set_errno(err); 84 return VFS_ERROR; 85} 86 87/*************************************************************************** 88 * Name: fallocate 89 * 90 * Description: 91 * The fallocate() function prepares or allocates a contiguous data area to the file. 92 * Thus the write file is guaranteed be contiguous and no allocation delay until the 93 * size reaches that size at least unless any other changes to the volume is performed. 94 * 95 * Parameters: 96 * fp Pointer to the open file object. 97 * mode Operation mode. only support FALLOC_FL_KEEP_SIZE. 98 * offset offset of the file to allocated. 99 * len The size to allocate for the file. 100 * 101 * Returned Value: 102 * On success, allocate contiguous data area to the file . On error, -1 is returned, and errno is set appro- 103 * priately: 104 * 105 * 106 ********************************************************************************************/ 107 108int fallocate64(int fd, int mode, off64_t offset, off64_t len) 109{ 110#if CONFIG_NFILE_DESCRIPTORS > 0 111 struct file *filep = NULL; 112#endif 113 114 /* Did we get a valid file descriptor? */ 115 116#if CONFIG_NFILE_DESCRIPTORS > 0 117 if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS) 118#endif 119 { 120 set_errno(EBADF); 121 return VFS_ERROR; 122 } 123 124#if CONFIG_NFILE_DESCRIPTORS > 0 125 126 /* The descriptor is in the right range to be a file descriptor... write 127 * to the file. 128 */ 129 130 int ret = fs_getfilep(fd, &filep); 131 if (ret < 0) { 132 /* The errno value has already been set */ 133 return VFS_ERROR; 134 } 135 136 if ((unsigned int)filep->f_oflags & O_DIRECTORY) { 137 set_errno(EBADF); 138 return VFS_ERROR; 139 } 140 141 /* Perform the fallocate operation using the file descriptor as an index */ 142 return file_fallocate64(filep, mode, offset, len); 143#endif 144} 145