summaryrefslogtreecommitdiff
path: root/firmware/include
diff options
context:
space:
mode:
authorWilliam Wilgus <wilgus.william@gmail.com>2022-03-03 07:37:03 -0500
committerWilliam Wilgus <wilgus.william@gmail.com>2022-03-03 18:58:07 -0500
commit9daacabd658508d2607a64b288c9bce7a635fb15 (patch)
treece96538ea82a4176f00f8eb9531711db7dea5750 /firmware/include
parentf88ea12bacf381ad4f39ba2328c806e772c0dda8 (diff)
downloadrockbox-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.h18
-rw-r--r--firmware/include/file_internal.h32
-rw-r--r--firmware/include/fileobj_mgr.h5
-rw-r--r--firmware/include/fs_defines.h6
-rw-r--r--firmware/include/rb_namespace.h79
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
124static inline void volume_onmount_internal(IF_MV_NONVOID(int volume)) 127static 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
132static inline void volume_onunmount_internal(IF_MV_NONVOID(int volume)) 145static 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
153static inline int readdir_dirent(struct filestr_base *stream, 167static 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);
229int open_noiso_internal(const char *path, int oflag); /* file.c */ 235int open_noiso_internal(const char *path, int oflag); /* file.c */
230void force_close_writer_internal(struct filestr_base *stream); /* file.c */ 236void force_close_writer_internal(struct filestr_base *stream); /* file.c */
231 237
232struct dirent; 238struct DIRENT;
233int uncached_readdir_dirent(struct filestr_base *stream, 239int 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);
236void uncached_rewinddir_dirent(struct dirscan_info *scanp); 242void uncached_rewinddir_dirent(struct dirscan_info *scanp);
237 243
238int uncached_readdir_internal(struct filestr_base *stream, 244int uncached_readdir_internal(struct filestr_base *stream,
@@ -333,7 +339,7 @@ static inline struct fat_direntry *get_dir_fatent(void)
333void iso_decode_d_name(char *d_name); 339void iso_decode_d_name(char *d_name);
334 340
335#ifdef HAVE_DIRCACHE 341#ifdef HAVE_DIRCACHE
336void empty_dirent(struct dirent *entry); 342void empty_dirent(struct DIRENT *entry);
337void fill_dirinfo_native(struct dirinfo_native *din); 343void 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);
29void file_binding_remove_next(struct file_base_binding *prevp, 29void file_binding_remove_next(struct file_base_binding *prevp,
30 struct file_base_binding *bindp); 30 struct file_base_binding *bindp);
31 31
32bool fileobj_mount(const struct file_base_info *srcinfop,
33 unsigned int callflags,
34 struct file_base_binding **bindpp);
35void fileobj_unmount(struct file_base_binding *bindp);
36
32void fileobj_fileop_open(struct filestr_base *stream, 37void 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
26enum 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
33struct ns_scan_info
34{
35 struct dirscan_info scan; /* dirscan info - first! */
36 int item; /* current item in parent */
37};
38
39/* root functions */
40int root_mount_path(const char *path, unsigned int flags);
41void root_unmount_volume(IF_MV_NONVOID(int volume));
42int root_readdir_dirent(struct filestr_base *stream,
43 struct ns_scan_info *scanp,
44 struct DIRENT *entry);
45
46/* namespace functions */
47int ns_parse_root(const char *path, const char **pathp, uint16_t *lenp);
48int ns_open_root(IF_MV(int volume,) unsigned int *callflagsp,
49 struct file_base_info *infop, uint16_t *attrp);
50int 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 */
54static inline int ns_close_stream(struct filestr_base *stream)
55{
56 return close_stream_internal(stream);
57}
58
59#include "dircache_redirect.h"
60
61static 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
68static 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 */