summaryrefslogtreecommitdiff
path: root/firmware/common/rb_namespace.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/common/rb_namespace.c')
-rw-r--r--firmware/common/rb_namespace.c74
1 files changed, 58 insertions, 16 deletions
diff --git a/firmware/common/rb_namespace.c b/firmware/common/rb_namespace.c
index ff5ad0f6db..52b2205f40 100644
--- a/firmware/common/rb_namespace.c
+++ b/firmware/common/rb_namespace.c
@@ -23,6 +23,7 @@
23#include "fileobj_mgr.h" 23#include "fileobj_mgr.h"
24#include "rb_namespace.h" 24#include "rb_namespace.h"
25#include "file_internal.h" 25#include "file_internal.h"
26#include <stdio.h> /*snprintf*/
26 27
27/* Define LOGF_ENABLE to enable logf output in this file */ 28/* Define LOGF_ENABLE to enable logf output in this file */
28//#define LOGF_ENABLE 29//#define LOGF_ENABLE
@@ -82,39 +83,48 @@ static void unmount_item(int item)
82 set_root_item_state(item, 0); 83 set_root_item_state(item, 0);
83} 84}
84 85
86static char *root_realpath_internal(void)
87{
88 static char root_realpath[ROOT_MAX_REALPATH];
89 return root_realpath;
90}
91const char* root_get_realpath(void)
92{
93 return root_realpath_internal();
94}
95
85/* mount the directory that enumerates into the root namespace */ 96/* mount the directory that enumerates into the root namespace */
86int root_mount_path(const char *path, unsigned int flags) 97int root_mount_path(const char *path, unsigned int flags)
87{ 98{
99 const char *folder = NULL; /* is a folder enumerated in the root? */
88#ifdef HAVE_MULTIVOLUME 100#ifdef HAVE_MULTIVOLUME
89 int volume = path_strip_volume(path, NULL, false); 101 int volume = path_strip_volume(path, &folder, false);
90 if (volume == ROOT_VOLUME) 102 if (volume == ROOT_VOLUME)
91 return -EINVAL; 103 return -EINVAL;
92
93 if (!CHECK_VOL(volume)) 104 if (!CHECK_VOL(volume))
94 return -ENOENT; 105 return -ENOENT;
106 char volname[VOL_MAX_LEN+2];
107 make_volume_root(volume, volname);
95#else 108#else
109 const char volname = PATH_ROOTSTR;
96 if (!path_is_absolute(path)) 110 if (!path_is_absolute(path))
97 { 111 {
98 logf("Path not absolute %s", path); 112 logf("Path not absolute %s", path);
99 return -ENOENT; 113 return -ENOENT;
100 } 114 }
115 path_dirname(path, &folder);
101#endif /* HAVE_MULTIVOLUME */ 116#endif /* HAVE_MULTIVOLUME */
102
103 bool contents = flags & NSITEM_CONTENTS; 117 bool contents = flags & NSITEM_CONTENTS;
104 int item = contents ? ROOT_CONTENTS_INDEX : IF_MV_VOL(volume); 118 int item = IF_MV_VOL(volume);
105 unsigned int state = get_root_item_state(item); 119 unsigned int state = get_root_item_state(item);
106
107 logf("%s: item:%d, st:%u, %s", __func__, item, state, path); 120 logf("%s: item:%d, st:%u, %s", __func__, item, state, path);
108 121 if (contents && state) /* volume must be mounted to enumerate into the root namespace */
109 if (state)
110 return -EBUSY;
111
112 if (contents)
113 { 122 {
123 if (get_root_item_state(ROOT_CONTENTS_INDEX))
124 return -EBUSY; /* error something is already enumerated */
114 /* cache information about the target */ 125 /* cache information about the target */
115 struct filestr_base stream; 126 struct filestr_base stream;
116 struct path_component_info compinfo; 127 struct path_component_info compinfo;
117
118 int e = errno; 128 int e = errno;
119 int rc = open_stream_internal(path, FF_DIR | FF_PROBE | FF_INFO | 129 int rc = open_stream_internal(path, FF_DIR | FF_PROBE | FF_INFO |
120 FF_DEVPATH, &stream, &compinfo); 130 FF_DEVPATH, &stream, &compinfo);
@@ -124,17 +134,41 @@ int root_mount_path(const char *path, unsigned int flags)
124 errno = e; 134 errno = e;
125 return rc; 135 return rc;
126 } 136 }
127
128 if (!fileobj_mount(&compinfo.info, FO_DIRECTORY, &root_bindp)) 137 if (!fileobj_mount(&compinfo.info, FO_DIRECTORY, &root_bindp))
129 return -EBUSY; 138 return -EBUSY;
130 } 139 int root_state = NSITEM_MOUNTED | (flags & (NSITEM_HIDDEN|NSITEM_CONTENTS));
140 set_root_item_state(ROOT_CONTENTS_INDEX, root_state);
141 flags |= state; /* preserve the state of the mounted volume */
142 if (!folder)
143 {
144 folder = "";
145 }
146 else
147 {
148 /*if a folder has been enumerated don't mark the whole volume */
149 if (folder[0] != '\0' && folder[1] != '\0')
150 flags &= ~NSITEM_CONTENTS;
131 151
152 }
153 snprintf(root_realpath_internal(), ROOT_MAX_REALPATH,"%s%s", volname, folder);
154 }
155 else if (state) /* error volume already mounted */
156 return -EBUSY;
132 state = NSITEM_MOUNTED | (flags & (NSITEM_HIDDEN|NSITEM_CONTENTS)); 157 state = NSITEM_MOUNTED | (flags & (NSITEM_HIDDEN|NSITEM_CONTENTS));
133 set_root_item_state(item, state); 158 set_root_item_state(item, state);
134
135 return 0; 159 return 0;
136} 160}
137 161
162/* check if volume in path is mounted in the root namespace */
163bool ns_volume_is_visible(IF_MV_NONVOID(int volume))
164{
165 int item = IF_MV_VOL(volume);
166 if ((item == ROOT_VOLUME) || !CHECK_VOL(item))
167 return false;
168 unsigned int state = get_root_item_state(item);
169 return state && (((state & NSITEM_HIDDEN) == 0) || (state & NSITEM_CONTENTS));
170}
171
138/* inform root that an entire volume is being unmounted */ 172/* inform root that an entire volume is being unmounted */
139void root_unmount_volume(IF_MV_NONVOID(int volume)) 173void root_unmount_volume(IF_MV_NONVOID(int volume))
140{ 174{
@@ -154,7 +188,10 @@ void root_unmount_volume(IF_MV_NONVOID(int volume))
154 uint32_t state = get_root_item_state(ROOT_CONTENTS_INDEX); 188 uint32_t state = get_root_item_state(ROOT_CONTENTS_INDEX);
155 if (state && (volume < 0 || BASEINFO_VOL(&root_bindp->info) == volume)) 189 if (state && (volume < 0 || BASEINFO_VOL(&root_bindp->info) == volume))
156#endif 190#endif
191 {
157 unmount_item(ROOT_CONTENTS_INDEX); 192 unmount_item(ROOT_CONTENTS_INDEX);
193 root_realpath_internal()[0] = '\0';
194 }
158} 195}
159 196
160/* parse the root part of a path */ 197/* parse the root part of a path */
@@ -268,8 +305,13 @@ int root_readdir_dirent(struct filestr_base *stream,
268 state = get_root_item_state(item); 305 state = get_root_item_state(item);
269 if ((state & (NSITEM_MOUNTED|NSITEM_HIDDEN)) == NSITEM_MOUNTED) 306 if ((state & (NSITEM_MOUNTED|NSITEM_HIDDEN)) == NSITEM_MOUNTED)
270 { 307 {
271 logf("Found mounted item: %d %s", item, entry->d_name); 308#if 1 /* hide the volume enumerated into the root namespace */
272 break; 309 if (item == ROOT_CONTENTS_INDEX || (state & NSITEM_CONTENTS) == 0)
310 {
311 logf("Found mounted item: %d %s", item, entry->d_name);
312 break;
313 }
314#endif
273 } 315 }
274 316
275 item++; 317 item++;