diff options
author | William Wilgus <wilgus.william@gmail.com> | 2022-03-03 07:37:03 -0500 |
---|---|---|
committer | William Wilgus <wilgus.william@gmail.com> | 2022-03-03 18:58:07 -0500 |
commit | 9daacabd658508d2607a64b288c9bce7a635fb15 (patch) | |
tree | ce96538ea82a4176f00f8eb9531711db7dea5750 /firmware/include | |
parent | f88ea12bacf381ad4f39ba2328c806e772c0dda8 (diff) | |
download | rockbox-9daacabd658508d2607a64b288c9bce7a635fb15.tar.gz rockbox-9daacabd658508d2607a64b288c9bce7a635fb15.zip |
[RESTORED!] Allow mounting of any directory as the root directory.
Provide definitions for the macros:
* RB_ROOT_VOL_HIDDEN(v) to exclude certain items from the root.
* RB_ROOT_CONTENTS to return a string with the name of the
directory to mount in the root.
Defaults are in export/rbpaths.h
It's a bit much for those that don't need the full functionality.
Some conditional define can cut it back a lot to cut out things only
needed if alternate root mounts are required. I'm just not bothering
yet. The basic concept would be applied to all targets to keep file
code from forking too much.
Change-Id: I3b5a14c530ff4b10d97f67636237d96875eb8969
Author: Michael Sevakis
Diffstat (limited to 'firmware/include')
-rw-r--r-- | firmware/include/dircache_redirect.h | 18 | ||||
-rw-r--r-- | firmware/include/file_internal.h | 32 | ||||
-rw-r--r-- | firmware/include/fileobj_mgr.h | 5 | ||||
-rw-r--r-- | firmware/include/fs_defines.h | 6 | ||||
-rw-r--r-- | firmware/include/rb_namespace.h | 79 |
5 files changed, 123 insertions, 17 deletions
diff --git a/firmware/include/dircache_redirect.h b/firmware/include/dircache_redirect.h index 9fae16b551..d7b9626c01 100644 --- a/firmware/include/dircache_redirect.h +++ b/firmware/include/dircache_redirect.h | |||
@@ -20,7 +20,10 @@ | |||
20 | ****************************************************************************/ | 20 | ****************************************************************************/ |
21 | #ifndef _DIRCACHE_REDIRECT_H_ | 21 | #ifndef _DIRCACHE_REDIRECT_H_ |
22 | 22 | ||
23 | #include "rbpaths.h" | ||
24 | #include "pathfuncs.h" | ||
23 | #include "dir.h" | 25 | #include "dir.h" |
26 | #include "dircache.h" | ||
24 | 27 | ||
25 | /*** | 28 | /*** |
26 | ** Internal redirects that depend upon whether or not dircache is made | 29 | ** Internal redirects that depend upon whether or not dircache is made |
@@ -123,10 +126,20 @@ static inline void fileop_onsync_internal(struct filestr_base *stream) | |||
123 | 126 | ||
124 | static inline void volume_onmount_internal(IF_MV_NONVOID(int volume)) | 127 | static inline void volume_onmount_internal(IF_MV_NONVOID(int volume)) |
125 | { | 128 | { |
129 | #ifdef HAVE_MULTIVOLUME | ||
130 | char path[VOL_MAX_LEN+2]; | ||
131 | make_volume_root(volume, path); | ||
132 | #else | ||
133 | const char *path = PATH_ROOTSTR; | ||
134 | #endif | ||
135 | root_mount_path(path, RB_ROOT_VOL_HIDDEN(volume) ? NSITEM_HIDDEN : 0); | ||
136 | #ifdef HAVE_MULTIVOLUME | ||
137 | if (volume == path_strip_volume(RB_ROOT_CONTENTS_DIR, NULL, false)) | ||
138 | #endif | ||
139 | root_mount_path(RB_ROOT_CONTENTS_DIR, NSITEM_CONTENTS); | ||
126 | #ifdef HAVE_DIRCACHE | 140 | #ifdef HAVE_DIRCACHE |
127 | dircache_mount(); | 141 | dircache_mount(); |
128 | #endif | 142 | #endif |
129 | IF_MV( (void)volume; ) | ||
130 | } | 143 | } |
131 | 144 | ||
132 | static inline void volume_onunmount_internal(IF_MV_NONVOID(int volume)) | 145 | static inline void volume_onunmount_internal(IF_MV_NONVOID(int volume)) |
@@ -135,6 +148,7 @@ static inline void volume_onunmount_internal(IF_MV_NONVOID(int volume)) | |||
135 | /* First, to avoid update of something about to be destroyed anyway */ | 148 | /* First, to avoid update of something about to be destroyed anyway */ |
136 | dircache_unmount(IF_MV(volume)); | 149 | dircache_unmount(IF_MV(volume)); |
137 | #endif | 150 | #endif |
151 | root_unmount_volume(IF_MV(volume)); | ||
138 | fileobj_mgr_unmount(IF_MV(volume)); | 152 | fileobj_mgr_unmount(IF_MV(volume)); |
139 | } | 153 | } |
140 | 154 | ||
@@ -152,7 +166,7 @@ static inline void fileop_onunmount_internal(struct filestr_base *stream) | |||
152 | 166 | ||
153 | static inline int readdir_dirent(struct filestr_base *stream, | 167 | static inline int readdir_dirent(struct filestr_base *stream, |
154 | struct dirscan_info *scanp, | 168 | struct dirscan_info *scanp, |
155 | struct dirent *entry) | 169 | struct DIRENT *entry) |
156 | { | 170 | { |
157 | #ifdef HAVE_DIRCACHE | 171 | #ifdef HAVE_DIRCACHE |
158 | return dircache_readdir_dirent(stream, scanp, entry); | 172 | return dircache_readdir_dirent(stream, scanp, entry); |
diff --git a/firmware/include/file_internal.h b/firmware/include/file_internal.h index d62b5a8541..ec0c5d28f0 100644 --- a/firmware/include/file_internal.h +++ b/firmware/include/file_internal.h | |||
@@ -30,6 +30,7 @@ | |||
30 | #include "fs_attr.h" | 30 | #include "fs_attr.h" |
31 | #include "fs_defines.h" | 31 | #include "fs_defines.h" |
32 | #include "fat.h" | 32 | #include "fat.h" |
33 | #include "dir.h" | ||
33 | #ifdef HAVE_DIRCACHE | 34 | #ifdef HAVE_DIRCACHE |
34 | #include "dircache.h" | 35 | #include "dircache.h" |
35 | #endif | 36 | #endif |
@@ -72,17 +73,20 @@ enum fildes_and_obj_flags | |||
72 | /* used in descriptor and common */ | 73 | /* used in descriptor and common */ |
73 | FDO_BUSY = 0x0001, /* descriptor/object is in use */ | 74 | FDO_BUSY = 0x0001, /* descriptor/object is in use */ |
74 | /* only used in individual stream descriptor */ | 75 | /* only used in individual stream descriptor */ |
75 | FD_WRITE = 0x0002, /* descriptor has write mode */ | 76 | FD_VALID = 0x0002, /* descriptor is valid but not registered */ |
76 | FD_WRONLY = 0x0004, /* descriptor is write mode only */ | 77 | FD_WRITE = 0x0004, /* descriptor has write mode */ |
77 | FD_APPEND = 0x0008, /* descriptor is append mode */ | 78 | FD_WRONLY = 0x0008, /* descriptor is write mode only */ |
79 | FD_APPEND = 0x0010, /* descriptor is append mode */ | ||
78 | FD_NONEXIST = 0x8000, /* closed but not freed (uncombined) */ | 80 | FD_NONEXIST = 0x8000, /* closed but not freed (uncombined) */ |
79 | /* only used as common flags */ | 81 | /* only used as common flags */ |
80 | FO_DIRECTORY = 0x0010, /* fileobj is a directory */ | 82 | FO_DIRECTORY = 0x0020, /* fileobj is a directory */ |
81 | FO_TRUNC = 0x0020, /* fileobj is opened to be truncated */ | 83 | FO_TRUNC = 0x0040, /* fileobj is opened to be truncated */ |
82 | FO_REMOVED = 0x0040, /* fileobj was deleted while open */ | 84 | FO_REMOVED = 0x0080, /* fileobj was deleted while open */ |
83 | FO_SINGLE = 0x0080, /* fileobj has only one stream open */ | 85 | FO_SINGLE = 0x0100, /* fileobj has only one stream open */ |
84 | FDO_MASK = 0x00ff, | 86 | FO_MOUNTTARGET = 0x0200, /* fileobj kept open as a mount target */ |
85 | FDO_CHG_MASK = FO_TRUNC, /* fileobj permitted external change */ | 87 | FDO_MASK = 0x03ff, |
88 | FDO_CHG_MASK = FO_TRUNC, | ||
89 | /* fileobj permitted external change */ /* fileobj permitted external change */ | ||
86 | /* bitflags that instruct various 'open' functions how to behave; | 90 | /* bitflags that instruct various 'open' functions how to behave; |
87 | * saved in stream flags (only) but not used by manager */ | 91 | * saved in stream flags (only) but not used by manager */ |
88 | FF_FILE = 0x00000000, /* expect file; accept file only */ | 92 | FF_FILE = 0x00000000, /* expect file; accept file only */ |
@@ -95,7 +99,9 @@ enum fildes_and_obj_flags | |||
95 | FF_CACHEONLY = 0x00200000, /* succeed only if in dircache */ | 99 | FF_CACHEONLY = 0x00200000, /* succeed only if in dircache */ |
96 | FF_INFO = 0x00400000, /* return info on self */ | 100 | FF_INFO = 0x00400000, /* return info on self */ |
97 | FF_PARENTINFO = 0x00800000, /* return info on parent */ | 101 | FF_PARENTINFO = 0x00800000, /* return info on parent */ |
98 | FF_MASK = 0x00ff0000, | 102 | FF_DEVPATH = 0x01000000, /* path is a device path, not root-based */ |
103 | FF_NOFS = 0x02000000, /* no filesystem mounted here */ | ||
104 | FF_MASK = 0x03ff0000, | ||
99 | }; | 105 | }; |
100 | 106 | ||
101 | /** Common data structures used throughout **/ | 107 | /** Common data structures used throughout **/ |
@@ -229,10 +235,10 @@ int test_stream_exists_internal(const char *path, unsigned int callflags); | |||
229 | int open_noiso_internal(const char *path, int oflag); /* file.c */ | 235 | int open_noiso_internal(const char *path, int oflag); /* file.c */ |
230 | void force_close_writer_internal(struct filestr_base *stream); /* file.c */ | 236 | void force_close_writer_internal(struct filestr_base *stream); /* file.c */ |
231 | 237 | ||
232 | struct dirent; | 238 | struct DIRENT; |
233 | int uncached_readdir_dirent(struct filestr_base *stream, | 239 | int uncached_readdir_dirent(struct filestr_base *stream, |
234 | struct dirscan_info *scanp, | 240 | struct dirscan_info *scanp, |
235 | struct dirent *entry); | 241 | struct DIRENT *entry); |
236 | void uncached_rewinddir_dirent(struct dirscan_info *scanp); | 242 | void uncached_rewinddir_dirent(struct dirscan_info *scanp); |
237 | 243 | ||
238 | int uncached_readdir_internal(struct filestr_base *stream, | 244 | int uncached_readdir_internal(struct filestr_base *stream, |
@@ -333,7 +339,7 @@ static inline struct fat_direntry *get_dir_fatent(void) | |||
333 | void iso_decode_d_name(char *d_name); | 339 | void iso_decode_d_name(char *d_name); |
334 | 340 | ||
335 | #ifdef HAVE_DIRCACHE | 341 | #ifdef HAVE_DIRCACHE |
336 | void empty_dirent(struct dirent *entry); | 342 | void empty_dirent(struct DIRENT *entry); |
337 | void fill_dirinfo_native(struct dirinfo_native *din); | 343 | void fill_dirinfo_native(struct dirinfo_native *din); |
338 | #endif /* HAVE_DIRCACHE */ | 344 | #endif /* HAVE_DIRCACHE */ |
339 | 345 | ||
diff --git a/firmware/include/fileobj_mgr.h b/firmware/include/fileobj_mgr.h index 627d2df341..0db3520d34 100644 --- a/firmware/include/fileobj_mgr.h +++ b/firmware/include/fileobj_mgr.h | |||
@@ -29,6 +29,11 @@ void file_binding_remove(struct file_base_binding *bindp); | |||
29 | void file_binding_remove_next(struct file_base_binding *prevp, | 29 | void file_binding_remove_next(struct file_base_binding *prevp, |
30 | struct file_base_binding *bindp); | 30 | struct file_base_binding *bindp); |
31 | 31 | ||
32 | bool fileobj_mount(const struct file_base_info *srcinfop, | ||
33 | unsigned int callflags, | ||
34 | struct file_base_binding **bindpp); | ||
35 | void fileobj_unmount(struct file_base_binding *bindp); | ||
36 | |||
32 | void fileobj_fileop_open(struct filestr_base *stream, | 37 | void fileobj_fileop_open(struct filestr_base *stream, |
33 | const struct file_base_info *srcinfop, | 38 | const struct file_base_info *srcinfop, |
34 | unsigned int callflags); | 39 | unsigned int callflags); |
diff --git a/firmware/include/fs_defines.h b/firmware/include/fs_defines.h index 538c4b36cd..a1938c56b8 100644 --- a/firmware/include/fs_defines.h +++ b/firmware/include/fs_defines.h | |||
@@ -51,11 +51,13 @@ | |||
51 | /* internal functions open streams as well; make sure they don't fail if all | 51 | /* internal functions open streams as well; make sure they don't fail if all |
52 | user descs are busy; this needs to be at least the greatest quantity needed | 52 | user descs are busy; this needs to be at least the greatest quantity needed |
53 | at once by all internal functions */ | 53 | at once by all internal functions */ |
54 | #define MOUNT_AUX_FILEOBJS 1 | ||
54 | #ifdef HAVE_DIRCACHE | 55 | #ifdef HAVE_DIRCACHE |
55 | #define AUX_FILEOBJS 3 | 56 | #define DIRCACHE_AUX_FILEOBJS 1 |
56 | #else | 57 | #else |
57 | #define AUX_FILEOBJS 2 | 58 | #define DIRCACHE_AUX_FILEOBJS 0 |
58 | #endif | 59 | #endif |
60 | #define AUX_FILEOBJS (2+DIRCACHE_AUX_FILEOBJS+MOUNT_AUX_FILEOBJS) | ||
59 | 61 | ||
60 | /* number of components statically allocated to handle the vast majority | 62 | /* number of components statically allocated to handle the vast majority |
61 | of path depths; should maybe be tuned for >= 90th percentile but for now, | 63 | of path depths; should maybe be tuned for >= 90th percentile but for now, |
diff --git a/firmware/include/rb_namespace.h b/firmware/include/rb_namespace.h new file mode 100644 index 0000000000..7bc711b5a6 --- /dev/null +++ b/firmware/include/rb_namespace.h | |||
@@ -0,0 +1,79 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2017 by Michael Sevakis | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #ifndef RB_NAMESPACE_H | ||
22 | #define RB_NAMESPACE_H | ||
23 | |||
24 | #include "file_internal.h" | ||
25 | |||
26 | enum ns_item_flags | ||
27 | { | ||
28 | NSITEM_MOUNTED = 0x01, /* item is mounted */ | ||
29 | NSITEM_HIDDEN = 0x02, /* item is not enumerated */ | ||
30 | NSITEM_CONTENTS = 0x04, /* contents enumerate */ | ||
31 | }; | ||
32 | |||
33 | struct ns_scan_info | ||
34 | { | ||
35 | struct dirscan_info scan; /* dirscan info - first! */ | ||
36 | int item; /* current item in parent */ | ||
37 | }; | ||
38 | |||
39 | /* root functions */ | ||
40 | int root_mount_path(const char *path, unsigned int flags); | ||
41 | void root_unmount_volume(IF_MV_NONVOID(int volume)); | ||
42 | int root_readdir_dirent(struct filestr_base *stream, | ||
43 | struct ns_scan_info *scanp, | ||
44 | struct DIRENT *entry); | ||
45 | |||
46 | /* namespace functions */ | ||
47 | int ns_parse_root(const char *path, const char **pathp, uint16_t *lenp); | ||
48 | int ns_open_root(IF_MV(int volume,) unsigned int *callflagsp, | ||
49 | struct file_base_info *infop, uint16_t *attrp); | ||
50 | int ns_open_stream(const char *path, unsigned int callflags, | ||
51 | struct filestr_base *stream, struct ns_scan_info *scanp); | ||
52 | |||
53 | /* closes the namespace stream */ | ||
54 | static inline int ns_close_stream(struct filestr_base *stream) | ||
55 | { | ||
56 | return close_stream_internal(stream); | ||
57 | } | ||
58 | |||
59 | #include "dircache_redirect.h" | ||
60 | |||
61 | static inline void ns_dirscan_rewind(struct ns_scan_info *scanp) | ||
62 | { | ||
63 | rewinddir_dirent(&scanp->scan); | ||
64 | if (scanp->item != -1) | ||
65 | scanp->item = 0; | ||
66 | } | ||
67 | |||
68 | static inline int ns_readdir_dirent(struct filestr_base *stream, | ||
69 | struct ns_scan_info *scanp, | ||
70 | struct dirent *entry) | ||
71 | |||
72 | { | ||
73 | if (scanp->item == -1) | ||
74 | return readdir_dirent(stream, &scanp->scan, entry); | ||
75 | else | ||
76 | return root_readdir_dirent(stream, scanp, entry); | ||
77 | } | ||
78 | |||
79 | #endif /* RB_NAMESPACE_H */ | ||