• 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 #include "stdlib.h"
17 #include "string.h"
18 #include "securec.h"
19 #include "vfs_mount.h"
20 #include "vfs_files.h"
21 #include "vfs_maps.h"
22 #include "vfs_config.h"
23 #include "vfs_operations.h"
24 #include "prt_fs.h"
25 
26 static struct TagMountPoint *g_mountPoints;
27 
OsMpDeleteFromList(struct TagMountPoint * mp)28 static void OsMpDeleteFromList(struct TagMountPoint *mp)
29 {
30     struct TagMountPoint *prev = NULL;
31 
32     if (g_mountPoints == mp) {
33         g_mountPoints = mp->mNext;
34         return;
35     }
36 
37     for (prev = g_mountPoints; prev != NULL; prev = prev->mNext) {
38         if (prev->mNext != mp) {
39             continue;
40         }
41 
42         prev->mNext = mp->mNext;
43         break;
44     }
45 }
46 
OsVfsFindMpByPath(const char * mPath,const char * iPath)47 static S32 OsVfsFindMpByPath(const char *mPath, const char *iPath)
48 {
49     const char *t = NULL;
50     S32 matches = 0;
51     do {
52         while ((*mPath == '/') && (*(mPath + 1) != '/')) {
53             mPath++;
54         }
55         while ((*iPath == '/') && (*(iPath + 1) != '/')) {
56             iPath++;
57         }
58 
59         t = strchr(mPath, '/');
60         if (t == NULL) {
61             t = strchr(mPath, '\0');
62         }
63         if ((t == mPath) || (t == NULL)) {
64             break;
65         }
66         if (strncmp(mPath, iPath, (size_t)(t - mPath)) != 0) {
67             return 0;
68         }
69 
70         iPath += (t - mPath);
71         if ((*iPath != '\0') && (*iPath != '/')) {
72             return 0;
73         }
74 
75         matches += (t - mPath);
76         mPath += (t - mPath);
77     } while (*mPath != '\0');
78 
79     return matches;
80 }
81 
OsVfsFindMp(const char * path,const char ** pathInMp)82 struct TagMountPoint *OsVfsFindMp(const char *path, const char **pathInMp)
83 {
84     struct TagMountPoint *mp = g_mountPoints;
85     struct TagMountPoint *bestMp = NULL;
86     const char *iPath = NULL;
87     S32 bestMatches = 0;
88     S32 matches;
89 
90     if (path == NULL) {
91         return NULL;
92     }
93 
94     if (pathInMp != NULL) {
95         *pathInMp = NULL;
96     }
97 
98     while ((mp != NULL) && (mp->mPath != NULL)) {
99         matches = OsVfsFindMpByPath(mp->mPath, path);
100         if (matches > bestMatches) {
101             bestMatches = matches;
102             bestMp = mp;
103 
104             iPath = path + matches;
105             while ((*iPath == '/') && (*(iPath + 1) != '/')) {
106                 iPath++;
107             }
108 
109             if (pathInMp != NULL) {
110                 *pathInMp = path;
111             }
112         }
113         mp = mp->mNext;
114     }
115     return bestMp;
116 }
117 
OsVfsFindMountPoint(const char * fsType)118 S32 OsVfsFindMountPoint(const char *fsType)
119 {
120     struct TagMountPoint *iter = NULL;
121     for (iter = g_mountPoints; iter != NULL; iter = iter->mNext) {
122         if ((iter->mFs != NULL) && (iter->mFs->fsType != NULL) &&
123             strcmp(iter->mFs->fsType, fsType) == 0) {
124             return FS_OK;
125         }
126     }
127     return FS_NOK;
128 }
129 
OsVfsFreeMp(struct TagMountPoint * mp)130 static void OsVfsFreeMp(struct TagMountPoint *mp)
131 {
132     if (mp == NULL) {
133         return;
134     }
135     if (mp->mPath != NULL) {
136         free((void *)mp->mPath);
137     }
138     if (mp->mDev != NULL) {
139         free((void *)mp->mDev);
140     }
141     free(mp);
142 }
143 
OsVfsMount(const char * source,const char * target,const char * filesystemtype,uintptr_t mountflags,const void * data)144 S32 OsVfsMount(const char *source, const char *target,
145                            const char *filesystemtype, uintptr_t mountflags,
146                            const void *data)
147 {
148     S32 ret;
149     struct TagMountPoint *mp = NULL;
150     struct TagFsMap *mFs = NULL;
151     const char *pathInMp = NULL;
152 
153     if ((target == NULL) || (target[0] != '/')) {
154         return FS_NOK;
155     }
156     (void)OsVfsLock();
157     /* 确认是否已经被挂载 */
158     mp = OsVfsFindMp(target, &pathInMp);
159     if (mp != NULL && pathInMp != NULL) {
160         OsVfsUnlock();
161         return FS_NOK;
162     }
163 
164     mFs = OsVfsGetFsMap(filesystemtype);
165     if ((mFs == NULL) || (mFs->fsMops == NULL) || (mFs->fsMops->mount == NULL)) {
166         OsVfsUnlock();
167         return FS_NOK;
168     }
169 
170     mp = (struct TagMountPoint *)malloc(sizeof(struct TagMountPoint));
171     if (mp == NULL) {
172         OsVfsUnlock();
173         return FS_NOK;
174     }
175     if (memset_s(mp, sizeof(struct TagMountPoint), 0, sizeof(struct TagMountPoint)) != EOK) {
176         free(mp);
177         OsVfsUnlock();
178         return FS_NOK;
179     }
180 
181     mp->mFs = mFs;
182     mp->mDev = NULL;
183     if (source != NULL) {
184         mp->mDev = strdup(source);
185         if (mp->mDev == NULL) {
186             OsVfsFreeMp(mp);
187             OsVfsUnlock();
188             return FS_NOK;
189         }
190     }
191     mp->mPath = strdup(target);
192     if (mp->mPath == NULL) {
193         OsVfsFreeMp(mp);
194         OsVfsUnlock();
195         return FS_NOK;
196     }
197 
198     ret = mp->mFs->fsMops->mount(mp, mountflags, data);
199     if (ret != 0) {
200         OsVfsFreeMp(mp);
201         OsVfsUnlock();
202         return FS_NOK;
203     }
204     mp->mRefs = 0;
205     mp->mWriteEnable = (mountflags & MS_RDONLY) ? FALSE : TRUE;
206     mp->mFs->fsRefs++;
207     mp->mNext = g_mountPoints;
208     g_mountPoints = mp;
209     OsVfsUnlock();
210     return FS_OK;
211 }
212 
OsVfsUmount(const char * target)213 S32 OsVfsUmount(const char *target)
214 {
215     struct TagMountPoint *mp = NULL;
216     const char *pathInMp = NULL;
217     S32 ret = FS_NOK;
218 
219     if (target == NULL) {
220         return ret;
221     }
222 
223     (void)OsVfsLock();
224     mp = OsVfsFindMp(target, &pathInMp);
225     if ((mp == NULL) || (mp->mRefs != 0) ||
226         (mp->mFs == NULL) || (mp->mFs->fsMops == NULL) ||
227         (mp->mFs->fsMops->umount == NULL)) {
228         OsVfsUnlock();
229         return ret;
230     }
231 
232     ret = mp->mFs->fsMops->umount(mp);
233     if (ret != 0) {
234         OsVfsUnlock();
235         return ret;
236     }
237 
238     OsMpDeleteFromList(mp);
239     mp->mFs->fsRefs--;
240     free((void *)mp->mPath);
241     free((void *)mp->mDev);
242     free(mp);
243 
244     OsVfsUnlock();
245     return FS_OK;
246 }
247 
OsCloseFdsInMp(struct TagMountPoint * mp)248 static void OsCloseFdsInMp(struct TagMountPoint *mp)
249 {
250     for (S32 fd = 0; fd < NR_OPEN_DEFAULT; fd++) {
251         struct TagFile *f = OsFdToFile(fd);
252         if (f == NULL) {
253             continue;
254         }
255         if ((f->fMp == mp) &&
256             (f->fFops != NULL) &&
257             (f->fFops->close != NULL)) {
258             (void)f->fFops->close(f);
259         }
260     }
261 }
OsVfsUmount2(const char * target,S32 flag)262 S32 OsVfsUmount2(const char *target, S32 flag)
263 {
264     struct TagMountPoint *mp = NULL;
265     const char *pathInMp = NULL;
266     S32 ret = FS_NOK;
267 
268     if (target == NULL) {
269         return ret;
270     }
271 
272     (void)OsVfsLock();
273     mp = OsVfsFindMp(target, &pathInMp);
274     if ((mp == NULL) || (mp->mRefs != 0) ||
275         (mp->mFs == NULL) || (mp->mFs->fsMops == NULL) ||
276         (mp->mFs->fsMops->umount2 == NULL)) {
277         OsVfsUnlock();
278         return ret;
279     }
280 
281     /* 关闭当前挂载节点下的所有文件 */
282     if ((U32)flag & MNT_FORCE) {
283         OsCloseFdsInMp(mp);
284     }
285 
286     ret = mp->mFs->fsMops->umount2(mp, flag);
287     if (ret != 0) {
288         OsVfsUnlock();
289         return FS_NOK;
290     }
291 
292     OsMpDeleteFromList(mp);
293     mp->mFs->fsRefs--;
294     free((void *)mp->mPath);
295     free((void *)mp->mDev);
296     free(mp);
297 
298     OsVfsUnlock();
299     return FS_OK;
300 }
301 
302