1 /*
2 * Copyright (c) 2023 Institute of Parallel And Distributed Systems (IPADS), Shanghai Jiao Tong University (SJTU)
3 * Licensed under the Mulan PSL v2.
4 * You can use this software according to the terms and conditions of the Mulan PSL v2.
5 * You may obtain a copy of Mulan PSL v2 at:
6 * http://license.coscl.org.cn/MulanPSL2
7 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
8 * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
9 * PURPOSE.
10 * See the Mulan PSL v2 for more details.
11 */
12 #include "mount_info.h"
13
14 struct list_head mount_point_infos;
15
16 /* Insert new mount_point at BEGINNING */
set_mount_point(const char * path,int path_len,int fs_cap)17 struct mount_point_info_node *set_mount_point(const char *path, int path_len,
18 int fs_cap)
19 {
20 struct mount_point_info_node *n;
21 n = (struct mount_point_info_node *)malloc(sizeof(*n));
22 BUG_ON(n == NULL);
23
24 BUG_ON(path_len > MAX_MOUNT_POINT_LEN);
25
26 strncpy(n->path, path, path_len);
27 n->path[path_len] = '\0';
28 n->path_len = path_len;
29 n->fs_cap = fs_cap;
30
31 list_add(&n->node, &mount_point_infos);
32 return n;
33 }
34
mount_point_match(struct mount_point_info_node * mp,char * path,int path_len)35 static bool mount_point_match(struct mount_point_info_node *mp, char *path,
36 int path_len)
37 {
38 /* Root */
39 if (mp->path_len == 1 && path[0] == '/')
40 return true;
41
42 /* Others */
43 if (strncmp(mp->path, path, mp->path_len) != 0)
44 return false;
45 if (path_len == mp->path_len)
46 return true;
47 if (path[mp->path_len] == '/')
48 return true;
49 return false;
50 }
51
52 /* Return the longest FIRST mount_point */
get_mount_point(char * path,int path_len)53 struct mount_point_info_node *get_mount_point(char *path, int path_len)
54 {
55 struct mount_point_info_node *iter;
56
57 int match_len_max = 0;
58 struct mount_point_info_node *matched_fs = NULL;
59
60 for_each_in_list (
61 iter, struct mount_point_info_node, node, &mount_point_infos) {
62 if (iter->path_len <= path_len && iter->path_len > match_len_max
63 && mount_point_match(iter, path, path_len)) {
64 matched_fs = iter;
65 match_len_max = iter->path_len;
66 }
67 }
68
69 BUG_ON(matched_fs == NULL);
70 return matched_fs;
71 }
72
73 /* Remove the FIRST mount_point matched */
remove_mount_point(char * path)74 int remove_mount_point(char *path)
75 {
76 struct mount_point_info_node *iter;
77
78 for_each_in_list (
79 iter, struct mount_point_info_node, node, &mount_point_infos) {
80 if (strcmp(iter->path, path) == 0) {
81 list_del(&iter->node);
82 free(iter);
83 return 0;
84 }
85 }
86 return -1;
87 }