• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2022 Huawei Technologies Co., Ltd. All rights reserved.
3  *
4  * UniProton is licensed under Mulan PSL v2.
5  * You can use this software according to the terms and conditions of the Mulan PSL v2.
6  * You may obtain a copy of Mulan PSL v2 at:
7  *          http://license.coscl.org.cn/MulanPSL2
8  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
9  * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
10  * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
11  * See the Mulan PSL v2 for more details.
12  * Create: 2022-09-21
13  * Description: 文件系统vfs层
14  */
15 
16 #define _GNU_SOURCE 1
17 #include <stdint.h>
18 #include <string.h>
19 #include <stdlib.h>
20 #include <stdarg.h>
21 #include <unistd.h>
22 #include <sys/uio.h>
23 #include <pthread.h>
24 #include "errno.h"
25 #include "fcntl.h"
26 #include "limits.h"
27 #include "securec.h"
28 #include "prt_fs.h"
29 #include "vfs_config.h"
30 #include "vfs_files.h"
31 #include "vfs_maps.h"
32 #include "vfs_mount.h"
33 #include "vfs_operations.h"
34 #include "prt_task.h"
35 
36 #define FREE_AND_SET_NULL(ptr) do { \
37     free(ptr);                      \
38     ptr = NULL;                     \
39 } while (0)
40 
41 static pthread_mutex_t g_vfsMutex = PTHREAD_MUTEX_INITIALIZER;
42 
OsVfsLock(void)43 S32 OsVfsLock(void)
44 {
45     S32 ret = pthread_mutex_lock(&g_vfsMutex);
46     if (ret != 0) {
47         return FS_NOK;
48     }
49     return FS_OK;
50 }
51 
OsVfsUnlock(void)52 void OsVfsUnlock(void)
53 {
54     (void)pthread_mutex_unlock(&g_vfsMutex);
55     return;
56 }
57 
OsVfsOpen(const char * path,S32 flags,va_list ap)58 S32 OsVfsOpen(const char *path, S32 flags, va_list ap)
59 {
60     (void)ap;
61     struct TagFile *file = NULL;
62     S32 fd = -1;
63     const char *pathInMp = NULL;
64     struct TagMountPoint *mp = NULL;
65     TskHandle taskId = 0;
66 
67     if ((path == NULL) || (path[strlen(path) - 1] == '/')) {
68         VFS_ERRNO_SET(EINVAL);
69         return fd;
70     }
71 
72     if (OsVfsLock() != FS_OK) {
73         VFS_ERRNO_SET(EAGAIN);
74         return fd;
75     }
76 
77     mp = OsVfsFindMp(path, &pathInMp);
78     if ((mp == NULL) || (pathInMp == NULL) || (*pathInMp == '\0') ||
79         (mp->mFs->fsFops == NULL) || (mp->mFs->fsFops->open == NULL)) {
80         VFS_ERRNO_SET(ENOENT);
81         OsVfsUnlock();
82         return fd;
83     }
84 
85     if ((mp->mWriteEnable == FALSE) &&
86         (flags & (O_CREAT | O_WRONLY | O_RDWR))) {
87         VFS_ERRNO_SET(EACCES);
88         OsVfsUnlock();
89         return fd;
90     }
91 
92     file = OsVfsGetFile();
93     if (file == NULL) {
94         VFS_ERRNO_SET(ENFILE);
95         OsVfsUnlock();
96         return fd;
97     }
98 
99     file->fullPath = strdup(path);
100     if (file->fullPath == NULL) {
101         VFS_ERRNO_SET(ENOMEM);
102         OsVfsPutFile(file);
103         OsVfsUnlock();
104         return FS_NOK;
105     }
106 
107     (void)PRT_TaskSelf(&taskId);
108     file->fFlags = (U32)flags;
109     file->fOffset = 0;
110     file->fData = NULL;
111     file->fFops = mp->mFs->fsFops;
112     file->fMp = mp;
113     file->fOwner = taskId;
114 
115     if (file->fFops->open(file, pathInMp, flags) == 0) {
116         mp->mRefs++;
117         fd = OsFileToFd(file);
118         file->fStatus = FILE_STATUS_READY;
119     } else {
120         OsVfsPutFile(file);
121     }
122 
123     OsVfsUnlock();
124     return fd;
125 }
126 
OsVfsAttachFile(S32 fd,U32 status)127 static struct TagFile *OsVfsAttachFile(S32 fd, U32 status)
128 {
129     struct TagFile *file = NULL;
130 
131     if ((fd < 0) || (fd >= CONFIG_NFILE_DESCRIPTORS)) {
132         VFS_ERRNO_SET(EBADF);
133         return NULL;
134     }
135 
136     if (OsVfsLock() != FS_OK) {
137         VFS_ERRNO_SET(EFAULT);
138         return NULL;
139     }
140 
141     file = OsFdToFile(fd);
142     if ((file == NULL) || (file->fMp == NULL)) {
143         VFS_ERRNO_SET(EBADF);
144         OsVfsUnlock();
145         return NULL;
146     }
147 
148     if (file->fStatus != FILE_STATUS_READY) {
149         VFS_ERRNO_SET(EBADF);
150         OsVfsUnlock();
151         return NULL;
152     }
153 
154     file->fStatus = status;
155     return file;
156 }
157 
OsVfsAttachFileReady(S32 fd)158 static struct TagFile *OsVfsAttachFileReady(S32 fd)
159 {
160     return OsVfsAttachFile(fd, FILE_STATUS_READY);
161 }
162 
OsVfsAttachFileWithStatus(S32 fd,S32 status)163 static struct TagFile *OsVfsAttachFileWithStatus(S32 fd, S32 status)
164 {
165     return OsVfsAttachFile(fd, (U32)status);
166 }
167 
OsVfsDetachFile(const struct TagFile * file)168 static void OsVfsDetachFile(const struct TagFile *file)
169 {
170     (void)file;
171     OsVfsUnlock();
172 }
173 
OsVfsClose(S32 fd)174 S32 OsVfsClose(S32 fd)
175 {
176     S32 ret = FS_NOK;
177     struct TagFile *file = OsVfsAttachFileWithStatus(fd, FILE_STATUS_CLOSING);
178     if (file == NULL) {
179         return ret;
180     }
181 
182     if ((file->fFops != NULL) && (file->fFops->close != NULL)) {
183         ret = file->fFops->close(file);
184     } else {
185         VFS_ERRNO_SET(ENOTSUP);
186     }
187 
188     if ((ret == 0) && (file->fMp != NULL)) {
189         file->fMp->mRefs--;
190     }
191 
192     if (file->fullPath != NULL) {
193         free((void *)file->fullPath);
194     }
195 
196     OsVfsDetachFile(file);
197     OsVfsPutFile(file);
198     return ret;
199 }
200 
OsVfsRead(S32 fd,char * buff,size_t bytes)201 ssize_t OsVfsRead(S32 fd, char *buff, size_t bytes)
202 {
203     struct TagFile *file = NULL;
204     ssize_t ret = (ssize_t)-1;
205 
206     if (buff == NULL) {
207         VFS_ERRNO_SET(EFAULT);
208         return ret;
209     }
210 
211     if (bytes == 0) {
212         return 0;
213     }
214 
215     file = OsVfsAttachFileReady(fd);
216     if (file == NULL) {
217         return ret;
218     }
219 
220     if ((file->fFlags & O_ACCMODE) == O_WRONLY) {
221         VFS_ERRNO_SET(EACCES);
222     } else if ((file->fFops != NULL) && (file->fFops->read != NULL)) {
223         ret = file->fFops->read(file, buff, bytes);
224     } else {
225         VFS_ERRNO_SET(ENOTSUP);
226     }
227 
228     OsVfsDetachFile(file);
229     return ret;
230 }
231 
OsVfsWrite(S32 fd,const void * buff,size_t bytes)232 ssize_t OsVfsWrite(S32 fd, const void *buff, size_t bytes)
233 {
234     struct TagFile *file = NULL;
235     ssize_t ret = (ssize_t)FS_NOK;
236 
237     if ((buff == NULL) || (bytes == 0)) {
238         VFS_ERRNO_SET(EINVAL);
239         return ret;
240     }
241 
242     file = OsVfsAttachFileReady(fd);
243     if (file == NULL) {
244         return ret;
245     }
246 
247     if ((file->fFlags & O_ACCMODE) == O_RDONLY) {
248         VFS_ERRNO_SET(EACCES);
249     } else if ((file->fFops != NULL) && (file->fFops->write != NULL)) {
250         ret = file->fFops->write(file, buff, bytes);
251     } else {
252         VFS_ERRNO_SET(ENOTSUP);
253     }
254 
255     OsVfsDetachFile(file);
256     return ret;
257 }
258 
OsVfsLseek(S32 fd,off_t off,S32 whence)259 off_t OsVfsLseek(S32 fd, off_t off, S32 whence)
260 {
261     off_t ret = (off_t)FS_NOK;
262     struct TagFile *file = OsVfsAttachFileReady(fd);
263     if (file == NULL) {
264         return ret;
265     }
266 
267     if ((file->fFops == NULL) || (file->fFops->lseek == NULL)) {
268         ret = file->fOffset;
269     } else {
270         ret = file->fFops->lseek(file, off, whence);
271     }
272 
273     OsVfsDetachFile(file);
274     return ret;
275 }
276 
OsVfsStat(const char * path,struct stat * stat)277 S32 OsVfsStat(const char *path, struct stat *stat)
278 {
279     struct TagMountPoint *mp = NULL;
280     const char *pathInMp = NULL;
281     S32 ret = FS_NOK;
282 
283     if ((path == NULL) || (stat == NULL)) {
284         VFS_ERRNO_SET(EINVAL);
285         return ret;
286     }
287 
288     if (OsVfsLock() != FS_OK) {
289         VFS_ERRNO_SET(EAGAIN);
290         return ret;
291     }
292 
293     mp = OsVfsFindMp(path, &pathInMp);
294     if ((mp == NULL) || (pathInMp == NULL) || (*pathInMp == '\0')) {
295         VFS_ERRNO_SET(ENOENT);
296         OsVfsUnlock();
297         return ret;
298     }
299 
300     if (mp->mFs->fsFops->stat != NULL) {
301         ret = mp->mFs->fsFops->stat(mp, pathInMp, stat);
302     } else {
303         VFS_ERRNO_SET(ENOTSUP);
304     }
305 
306     OsVfsUnlock();
307     return ret;
308 }
309 
OsVfsFstat(S32 fd,struct stat * buf)310 S32 OsVfsFstat(S32 fd, struct stat *buf)
311 {
312     S32 ret;
313     struct TagFile *filep = OsVfsAttachFileReady(fd);
314     if ((filep == NULL) || (filep->fMp == NULL) || filep->fullPath == NULL) {
315         return FS_NOK;
316     }
317     ret = stat(filep->fullPath, buf);
318     OsVfsDetachFile(filep);
319     return ret;
320 }
321 
OsVfsStatfs(const char * path,struct statfs * buf)322 S32 OsVfsStatfs(const char *path, struct statfs *buf)
323 {
324     struct TagMountPoint *mp = NULL;
325     const char *pathInMp = NULL;
326     S32 ret = FS_NOK;
327 
328     if ((path == NULL) || (buf == NULL)) {
329         VFS_ERRNO_SET(EINVAL);
330         return ret;
331     }
332 
333     if (OsVfsLock() != FS_OK) {
334         VFS_ERRNO_SET(EAGAIN);
335         return ret;
336     }
337 
338     mp = OsVfsFindMp(path, &pathInMp);
339     if ((mp == NULL) || (pathInMp == NULL) || (*pathInMp == '\0')) {
340         VFS_ERRNO_SET(ENOENT);
341         OsVfsUnlock();
342         return ret;
343     }
344 
345     if (mp->mFs->fsFops->stat != NULL) {
346         ret = mp->mFs->fsMops->statfs(pathInMp, buf);
347     } else {
348         VFS_ERRNO_SET(ENOTSUP);
349     }
350 
351     OsVfsUnlock();
352     return ret;
353 }
354 
OsVfsUnlink(const char * path)355 S32 OsVfsUnlink(const char *path)
356 {
357     struct TagMountPoint *mp = NULL;
358     const char *pathInMp = NULL;
359     S32 ret = FS_NOK;
360 
361     if (path == NULL) {
362         VFS_ERRNO_SET(EINVAL);
363         return ret;
364     }
365 
366     if (OsVfsLock() != FS_OK) {
367         VFS_ERRNO_SET(EAGAIN);
368         return ret;
369     }
370 
371     mp = OsVfsFindMp(path, &pathInMp);
372     if ((mp == NULL) || (pathInMp == NULL) || (*pathInMp == '\0') ||
373         (mp->mFs->fsFops->unlink == NULL)) {
374         VFS_ERRNO_SET(ENOENT);
375         OsVfsUnlock();
376         return ret;
377     }
378 
379     ret = mp->mFs->fsFops->unlink(mp, pathInMp);
380 
381     OsVfsUnlock();
382     return ret;
383 }
384 
OsVfsRename(const char * oldName,const char * newName)385 S32 OsVfsRename(const char *oldName, const char *newName)
386 {
387     struct TagMountPoint *mpOld = NULL;
388     struct TagMountPoint *mpNew = NULL;
389     const char *pathInMpOld = NULL;
390     const char *pathInMpNew = NULL;
391     S32 ret = FS_NOK;
392 
393     if ((oldName == NULL) || (newName == NULL)) {
394         VFS_ERRNO_SET(EINVAL);
395         return ret;
396     }
397 
398     if (OsVfsLock() != FS_OK) {
399         VFS_ERRNO_SET(EAGAIN);
400         return ret;
401     }
402 
403     mpOld = OsVfsFindMp(oldName, &pathInMpOld);
404 
405     if (pathInMpOld == NULL) {
406         VFS_ERRNO_SET(EINVAL);
407         OsVfsUnlock();
408         return ret;
409     }
410 
411     if ((mpOld == NULL) || (*pathInMpOld == '\0') ||
412         (mpOld->mFs->fsFops->unlink == NULL)) {
413         VFS_ERRNO_SET(EINVAL);
414         OsVfsUnlock();
415         return ret;
416     }
417 
418     mpNew = OsVfsFindMp(newName, &pathInMpNew);
419     if ((mpNew == NULL) || (pathInMpNew == NULL) || (*pathInMpNew == '\0') || (mpNew->mFs->fsFops->unlink == NULL)) {
420         VFS_ERRNO_SET(EINVAL);
421         OsVfsUnlock();
422         return ret;
423     }
424 
425     if (mpOld != mpNew) {
426         VFS_ERRNO_SET(EXDEV);
427         OsVfsUnlock();
428         return ret;
429     }
430 
431     if (mpOld->mFs->fsFops->rename != NULL) {
432         ret = mpOld->mFs->fsFops->rename(mpOld, pathInMpOld, pathInMpNew);
433     } else {
434         VFS_ERRNO_SET(ENOTSUP);
435     }
436 
437     OsVfsUnlock();
438     return ret;
439 }
440 
OsVfsIoctl(S32 fd,S32 func,unsigned long arg)441 S32 OsVfsIoctl(S32 fd, S32 func, unsigned long arg)
442 {
443     S32 ret = FS_NOK;
444     struct TagFile *file = OsVfsAttachFileReady(fd);
445     if (file == NULL) {
446         return ret;
447     }
448 
449     if ((file->fFops != NULL) && (file->fFops->ioctl != NULL)) {
450         ret = file->fFops->ioctl(file, func, arg);
451     } else {
452         VFS_ERRNO_SET(ENOTSUP);
453     }
454 
455     OsVfsDetachFile(file);
456     return ret;
457 }
458 
OsVfsSync(S32 fd)459 S32 OsVfsSync(S32 fd)
460 {
461     S32 ret = FS_NOK;
462     struct TagFile *file = OsVfsAttachFileReady(fd);
463     if (file == NULL) {
464         return ret;
465     }
466 
467     if (file->fMp->mWriteEnable == FALSE) {
468         VFS_ERRNO_SET(EACCES);
469         OsVfsDetachFile(file);
470         return ret;
471     }
472 
473     if ((file->fFops != NULL) && (file->fFops->sync != NULL)) {
474         ret = file->fFops->sync(file);
475     } else {
476         VFS_ERRNO_SET(ENOTSUP);
477     }
478 
479     OsVfsDetachFile(file);
480     return ret;
481 }
482 
OsVfsOpendir(const char * path)483 DIR *OsVfsOpendir(const char *path)
484 {
485     struct TagMountPoint *mp = NULL;
486     const char *pathInMp = NULL;
487     struct TagDir *dir = NULL;
488     U32 ret;
489 
490     if (path == NULL) {
491         VFS_ERRNO_SET(EINVAL);
492         return NULL;
493     }
494 
495     dir = (struct TagDir *)malloc(sizeof(struct TagDir));
496     if (dir == NULL) {
497         VFS_ERRNO_SET(ENOMEM);
498         return NULL;
499     }
500 
501     if (OsVfsLock() != FS_OK) {
502         VFS_ERRNO_SET(EAGAIN);
503         free(dir);
504         return NULL;
505     }
506 
507     mp = OsVfsFindMp(path, &pathInMp);
508     if ((mp == NULL) || (pathInMp == NULL)) {
509         VFS_ERRNO_SET(ENOENT);
510         OsVfsUnlock();
511         free(dir);
512         return NULL;
513     }
514 
515     if (mp->mFs->fsFops->opendir == NULL) {
516         VFS_ERRNO_SET(ENOTSUP);
517         OsVfsUnlock();
518         free(dir);
519         return NULL;
520     }
521 
522     dir->dMp = mp;
523     dir->dOffset = 0;
524 
525     ret = (U32)mp->mFs->fsFops->opendir(dir, pathInMp);
526     if (ret == 0) {
527         mp->mRefs++;
528     } else {
529         free(dir);
530         dir = NULL;
531     }
532 
533     OsVfsUnlock();
534     return (DIR *)dir;
535 }
536 
OsVfsReaddir(DIR * d)537 struct dirent *OsVfsReaddir(DIR *d)
538 {
539     struct dirent *ret = NULL;
540     struct TagDir *dir = (struct TagDir *)d;
541 
542     if ((dir == NULL) || (dir->dMp == NULL)) {
543         VFS_ERRNO_SET(EINVAL);
544         return NULL;
545     }
546 
547     if (OsVfsLock() != FS_OK) {
548         VFS_ERRNO_SET(EAGAIN);
549         return NULL;
550     }
551 
552     if ((dir->dMp->mFs != NULL) && (dir->dMp->mFs->fsFops != NULL) &&
553         (dir->dMp->mFs->fsFops->readdir != NULL)) {
554         if (dir->dMp->mFs->fsFops->readdir(dir, &dir->dDent) == 0) {
555             ret = &dir->dDent;
556         }
557     } else {
558         VFS_ERRNO_SET(ENOTSUP);
559     }
560 
561     OsVfsUnlock();
562     return ret;
563 }
564 
OsVfsClosedir(DIR * d)565 S32 OsVfsClosedir(DIR *d)
566 {
567     struct TagMountPoint *mp = NULL;
568     S32 ret = FS_NOK;
569     struct TagDir *dir = (struct TagDir *)d;
570 
571     if ((dir == NULL) || (dir->dMp == NULL)) {
572         VFS_ERRNO_SET(EBADF);
573         return ret;
574     }
575 
576     mp = dir->dMp;
577 
578     if (OsVfsLock() != FS_OK) {
579         VFS_ERRNO_SET(EAGAIN);
580         return ret;
581     }
582 
583     if ((dir->dMp->mFs != NULL) && (dir->dMp->mFs->fsFops != NULL) &&
584         (dir->dMp->mFs->fsFops->closedir != NULL)) {
585         ret = dir->dMp->mFs->fsFops->closedir(dir);
586     } else {
587         VFS_ERRNO_SET(ENOTSUP);
588     }
589 
590     if (ret == 0) {
591         mp->mRefs--;
592     } else {
593         VFS_ERRNO_SET(EBADF);
594     }
595 
596     OsVfsUnlock();
597     free(dir);
598     dir = NULL;
599     return ret;
600 }
601 
OsVfsMkdir(const char * path,S32 mode)602 S32 OsVfsMkdir(const char *path, S32 mode)
603 {
604     struct TagMountPoint *mp = NULL;
605     const char *pathInMp = NULL;
606     S32 ret = FS_NOK;
607     (void)mode;
608 
609     if (path == NULL) {
610         VFS_ERRNO_SET(EINVAL);
611         return ret;
612     }
613 
614     if (OsVfsLock() != FS_OK) {
615         VFS_ERRNO_SET(EAGAIN);
616         return ret;
617     }
618 
619     mp = OsVfsFindMp(path, &pathInMp);
620     if ((mp == NULL) || (pathInMp == NULL) || (*pathInMp == '\0')) {
621         VFS_ERRNO_SET(ENOENT);
622         OsVfsUnlock();
623         return ret;
624     }
625 
626     if (mp->mFs->fsFops->mkdir != NULL) {
627         ret = mp->mFs->fsFops->mkdir(mp, pathInMp);
628     } else {
629         VFS_ERRNO_SET(ENOTSUP);
630         ret = FS_NOK;
631     }
632 
633     OsVfsUnlock();
634     return ret;
635 }
636 
OsVfsFcntl(S32 fd,S32 cmd,va_list ap)637 S32 OsVfsFcntl(S32 fd, S32 cmd, va_list ap)
638 {
639     S32 ret = FS_NOK;
640     U32 flags;
641     struct TagFile *filep = OsVfsAttachFileReady(fd);
642     if (filep == NULL) {
643         return ret;
644     }
645 
646     if (filep->fFops == NULL) {
647         VFS_ERRNO_SET(EBADF);
648         OsVfsDetachFile(filep);
649         return ret;
650     }
651 
652     if (cmd == F_GETFL) {
653         ret = (S32)(filep->fFlags);
654     } else if (cmd == F_SETFL) {
655         flags = (U32)va_arg(ap, S32);
656         flags &= PRT_FCNTL;
657         filep->fFlags &= ~PRT_FCNTL;
658         filep->fFlags |= flags;
659         ret = FS_OK;
660     } else {
661         VFS_ERRNO_SET(ENOSYS);
662     }
663     OsVfsDetachFile(filep);
664     va_end(ap);
665     return ret;
666 }
667 
OsVfsPread(S32 fd,void * buff,size_t bytes,off_t off)668 ssize_t OsVfsPread(S32 fd, void *buff, size_t bytes, off_t off)
669 {
670     off_t savepos, pos;
671     ssize_t ret;
672 
673     if (buff == NULL) {
674         VFS_ERRNO_SET(EFAULT);
675         return (ssize_t)FS_NOK;
676     }
677 
678     if (bytes == 0) {
679         return 0;
680     }
681 
682     if (OsVfsLock() != FS_OK) {
683         VFS_ERRNO_SET(EAGAIN);
684         return (ssize_t)FS_NOK;
685     }
686 
687     savepos = lseek(fd, 0, SEEK_CUR);
688     if (savepos == (off_t)-1) {
689         OsVfsUnlock();
690         return (ssize_t)FS_NOK;
691     }
692 
693     pos = lseek(fd, off, SEEK_SET);
694     if (pos == (off_t)-1) {
695         OsVfsUnlock();
696         return (ssize_t)FS_NOK;
697     }
698 
699     ret = read(fd, buff, bytes);
700     pos = lseek(fd, savepos, SEEK_SET);
701     if ((pos == (off_t)-1) && (ret >= 0)) {
702         OsVfsUnlock();
703         return (ssize_t)FS_NOK;
704     }
705 
706     OsVfsUnlock();
707     return ret;
708 }
709 
OsVfsPwrite(S32 fd,const void * buff,size_t bytes,off_t off)710 ssize_t OsVfsPwrite(S32 fd, const void *buff, size_t bytes, off_t off)
711 {
712     ssize_t ret;
713     off_t savepos, pos;
714 
715     if (buff == NULL) {
716         VFS_ERRNO_SET(EFAULT);
717         return (ssize_t)FS_NOK;
718     }
719 
720     if (bytes == 0) {
721         return 0;
722     }
723 
724     if (OsVfsLock() != FS_OK) {
725         VFS_ERRNO_SET(EAGAIN);
726         return (ssize_t)FS_NOK;
727     }
728 
729     savepos = lseek(fd, 0, SEEK_CUR);
730     if (savepos == (off_t)-1) {
731         OsVfsUnlock();
732         return (ssize_t)FS_NOK;
733     }
734 
735     pos = lseek(fd, off, SEEK_SET);
736     if (pos == (off_t)-1) {
737         OsVfsUnlock();
738         return (ssize_t)FS_NOK;
739     }
740 
741     ret = write(fd, buff, bytes);
742     pos = lseek(fd, savepos, SEEK_SET);
743     if ((pos == (off_t)-1) && (ret >= 0)) {
744         OsVfsUnlock();
745         return (ssize_t)FS_NOK;
746     }
747 
748     OsVfsUnlock();
749     return ret;
750 }
751 
OsVfsFtruncate(S32 fd,off_t length)752 S32 OsVfsFtruncate(S32 fd, off_t length)
753 {
754     S32 ret = FS_NOK;
755     struct TagFile *file = NULL;
756 
757     if (length <= 0) {
758         VFS_ERRNO_SET(EINVAL);
759         return ret;
760     }
761 
762     file = OsVfsAttachFileReady(fd);
763     if (file == NULL) {
764         return ret;
765     }
766 
767     if (file->fMp->mWriteEnable == FALSE) {
768         VFS_ERRNO_SET(EACCES);
769         OsVfsDetachFile(file);
770         return ret;
771     }
772 
773     if ((file->fFlags & O_ACCMODE) == O_RDONLY) {
774         VFS_ERRNO_SET(EACCES);
775     } else if ((file->fFops != NULL) && (file->fFops->truncate != NULL)) {
776         ret = file->fFops->truncate(file, length);
777     } else {
778         VFS_ERRNO_SET(ENOTSUP);
779     }
780 
781     OsVfsDetachFile(file);
782     return ret;
783 }
784 
OsVfsReadv(S32 fd,const struct iovec * iovBuf,S32 iovcnt)785 ssize_t OsVfsReadv(S32 fd, const struct iovec *iovBuf, S32 iovcnt)
786 {
787     S32 i;
788     errno_t ret;
789     char *buf = NULL;
790     char *curBuf = NULL;
791     char *readBuf = NULL;
792     size_t bufLen = 0;
793     size_t bytesToRead;
794     ssize_t totalBytesRead;
795     size_t totalLen;
796     const struct iovec *iov = (const struct iovec *)iovBuf;
797 
798     if ((iov == NULL) || (iovcnt <= 0) || (iovcnt > IOV_MAX_CNT)) {
799         return (ssize_t)FS_NOK;
800     }
801 
802     for (i = 0; i < iovcnt; ++i) {
803         if ((SSIZE_MAX - bufLen) < iov[i].iov_len) {
804             return (ssize_t)FS_NOK;
805         }
806         bufLen += iov[i].iov_len;
807     }
808     if (bufLen == 0) {
809         return (ssize_t)FS_NOK;
810     }
811     totalLen = bufLen * sizeof(char);
812     buf = (char *)malloc(totalLen);
813     if (buf == NULL) {
814         return (ssize_t)FS_NOK;
815     }
816 
817     totalBytesRead = read(fd, buf, bufLen);
818     if ((size_t)totalBytesRead < totalLen) {
819         totalLen = (size_t)totalBytesRead;
820     }
821     curBuf = buf;
822     for (i = 0; i < iovcnt; ++i) {
823         readBuf = (char *)iov[i].iov_base;
824         bytesToRead = iov[i].iov_len;
825 
826         size_t lenToRead = totalLen < bytesToRead ? totalLen : bytesToRead;
827         ret = memcpy_s(readBuf, bytesToRead, curBuf, lenToRead);
828         if (ret != EOK) {
829             free(buf);
830             return (ssize_t)FS_NOK;
831         }
832         if (totalLen < (size_t)bytesToRead) {
833             break;
834         }
835         curBuf += bytesToRead;
836         totalLen -= bytesToRead;
837     }
838     free(buf);
839     return totalBytesRead;
840 }
841 
OsVfsWritev(S32 fd,const struct iovec * iovBuf,S32 iovcnt)842 ssize_t OsVfsWritev(S32 fd, const struct iovec *iovBuf, S32 iovcnt)
843 {
844     S32 i;
845     errno_t ret;
846     char *buf = NULL;
847     char *curBuf = NULL;
848     char *writeBuf = NULL;
849     size_t bufLen = 0;
850     size_t bytesToWrite;
851     ssize_t totalBytesWritten;
852     size_t totalLen;
853     const struct iovec *iov = iovBuf;
854 
855     if ((iov == NULL) || (iovcnt <= 0) || (iovcnt > IOV_MAX_CNT)) {
856         return (ssize_t)FS_NOK;
857     }
858 
859     for (i = 0; i < iovcnt; ++i) {
860         if ((SSIZE_MAX - bufLen) < iov[i].iov_len) {
861             VFS_ERRNO_SET(EINVAL);
862             return (ssize_t)FS_NOK;
863         }
864         bufLen += iov[i].iov_len;
865     }
866     if (bufLen == 0) {
867         return (ssize_t)FS_NOK;
868     }
869     totalLen = bufLen * sizeof(char);
870     buf = (char *)malloc(totalLen);
871     if (buf == NULL) {
872         return (ssize_t)FS_NOK;
873     }
874     curBuf = buf;
875     for (i = 0; i < iovcnt; ++i) {
876         writeBuf = (char *)iov[i].iov_base;
877         bytesToWrite = iov[i].iov_len;
878         if (((ssize_t)totalLen <= 0) || ((ssize_t)bytesToWrite <= 0)) {
879             continue;
880         }
881         ret = memcpy_s(curBuf, totalLen, writeBuf, bytesToWrite);
882         if (ret != EOK) {
883             free(buf);
884             return (ssize_t)FS_NOK;
885         }
886         curBuf += bytesToWrite;
887         totalLen -= bytesToWrite;
888     }
889 
890     totalBytesWritten = write(fd, buf, bufLen);
891     free(buf);
892 
893     return totalBytesWritten;
894 }
895