summaryrefslogtreecommitdiff
path: root/firmware/include
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/include')
-rw-r--r--firmware/include/dircache.h40
-rw-r--r--firmware/include/dircache_redirect.h19
-rw-r--r--firmware/include/file_internal.h91
-rw-r--r--firmware/include/fileobj_mgr.h5
4 files changed, 104 insertions, 51 deletions
diff --git a/firmware/include/dircache.h b/firmware/include/dircache.h
index 7e8c764e7f..d73c6f6e81 100644
--- a/firmware/include/dircache.h
+++ b/firmware/include/dircache.h
@@ -57,6 +57,15 @@
57 figure pessimistic */ 57 figure pessimistic */
58typedef uint32_t dc_serial_t; 58typedef uint32_t dc_serial_t;
59 59
60/* these should agree with size of dc_serial_t */
61#define DC_SERHASH_START 0xffffffff
62
63/* I was originally using FNV hash but decided this is probably okay
64 (for now) */
65#define dc_hash_serialnum(s, h) \
66 ({ dc_serial_t __x = (s); crc_32(&(__x), sizeof(dc_serial_t), (h)); })
67#define DC_SERIAL_FMT "0x%08lX"
68
60/** 69/**
61 ****************************************************************************/ 70 ****************************************************************************/
62 71
@@ -132,10 +141,33 @@ void dircache_fileop_sync(struct file_base_binding *infop,
132 const struct dirinfo_native *dinp); 141 const struct dirinfo_native *dinp);
133 142
134 143
135/** Dircache paths and files **/ 144/** Dircache paths, files and shortcuts **/
136ssize_t dircache_get_path(const struct dircache_file *dcfilep, char *buf, 145struct dircache_fileref
137 size_t size); 146{
138int dircache_get_file(const char *path, struct dircache_file *dcfilep); 147 struct dircache_file dcfile;
148 dc_serial_t serialhash; /* Hash of serialnumbers to root */
149};
150
151void dircache_fileref_init(struct dircache_fileref *dcfrefp);
152ssize_t dircache_get_fileref_path(const struct dircache_fileref *dcfrefp,
153 char *buf, size_t size);
154
155/* Bitflags for dircache_search() */
156enum dircache_search_flags
157{
158 DCS_FILEREF = 0x01, /* Check fileref existence and serial number */
159 _DCS_VERIFY_FLAG = 0x02, /* Internal: Only valid with DCS_FILEREF */
160 DCS_FILEREF_VERIFY = 0x03, /* Do DCS_FILEREF check + verify serial hash */
161 DCS_CACHED_PATH = 0x04, /* Check only cache for provided path */
162 _DCS_STORAGE_FLAG = 0x08, /* Internal: Only valid with DCS_CACHED_PATH */
163 DCS_STORAGE_PATH = 0x0c, /* Read-through if needed for provided path */
164 DCS_UPDATE_FILEREF = 0x10, /* If fileref is not valid but path is found or
165 searching a path, update the reference
166 information */
167};
168
169int dircache_search(unsigned int flags, struct dircache_fileref *dcfrefp,
170 const char *path);
139 171
140 172
141/** Debug screen/info stuff **/ 173/** Debug screen/info stuff **/
diff --git a/firmware/include/dircache_redirect.h b/firmware/include/dircache_redirect.h
index 15fb4bc38d..9fae16b551 100644
--- a/firmware/include/dircache_redirect.h
+++ b/firmware/include/dircache_redirect.h
@@ -24,6 +24,8 @@
24 24
25/*** 25/***
26 ** Internal redirects that depend upon whether or not dircache is made 26 ** Internal redirects that depend upon whether or not dircache is made
27 **
28 ** Some stuff deals with it, some doesn't right now. This is a nexus point..
27 **/ 29 **/
28 30
29/** File binding **/ 31/** File binding **/
@@ -119,11 +121,6 @@ static inline void fileop_onsync_internal(struct filestr_base *stream)
119#endif 121#endif
120} 122}
121 123
122static inline void fileop_ontruncate_internal(struct filestr_base *stream)
123{
124 fileobj_fileop_truncate(stream);
125}
126
127static inline void volume_onmount_internal(IF_MV_NONVOID(int volume)) 124static inline void volume_onmount_internal(IF_MV_NONVOID(int volume))
128{ 125{
129#ifdef HAVE_DIRCACHE 126#ifdef HAVE_DIRCACHE
@@ -134,10 +131,20 @@ static inline void volume_onmount_internal(IF_MV_NONVOID(int volume))
134 131
135static inline void volume_onunmount_internal(IF_MV_NONVOID(int volume)) 132static inline void volume_onunmount_internal(IF_MV_NONVOID(int volume))
136{ 133{
137 fileobj_mgr_unmount(IF_MV(volume));
138#ifdef HAVE_DIRCACHE 134#ifdef HAVE_DIRCACHE
135 /* First, to avoid update of something about to be destroyed anyway */
139 dircache_unmount(IF_MV(volume)); 136 dircache_unmount(IF_MV(volume));
140#endif 137#endif
138 fileobj_mgr_unmount(IF_MV(volume));
139}
140
141static inline void fileop_onunmount_internal(struct filestr_base *stream)
142{
143
144 if (stream->flags & FD_WRITE)
145 force_close_writer_internal(stream); /* try to save stuff */
146 else
147 fileop_onclose_internal(stream); /* just readers, bye */
141} 148}
142 149
143 150
diff --git a/firmware/include/file_internal.h b/firmware/include/file_internal.h
index d1bb67406a..acec81206e 100644
--- a/firmware/include/file_internal.h
+++ b/firmware/include/file_internal.h
@@ -81,6 +81,7 @@
81#define ATTR_NEW_FILE (ATTR_ARCHIVE) 81#define ATTR_NEW_FILE (ATTR_ARCHIVE)
82#define ATTR_NEW_DIRECTORY (ATTR_DIRECTORY) 82#define ATTR_NEW_DIRECTORY (ATTR_DIRECTORY)
83 83
84#define ATTR_SYSTEM_ROOT (ATTR_SYSROOT | ATTR_DIRECTORY)
84#define ATTR_MOUNT_POINT (ATTR_VOLUME | ATTR_DIRECTORY) 85#define ATTR_MOUNT_POINT (ATTR_VOLUME | ATTR_DIRECTORY)
85 86
86/** File sector cache **/ 87/** File sector cache **/
@@ -110,33 +111,35 @@ void file_cache_free(struct filestr_cache *cachep);
110enum fildes_and_obj_flags 111enum fildes_and_obj_flags
111{ 112{
112 /* used in descriptor and common */ 113 /* used in descriptor and common */
113 FDO_BUSY = 0x0001, /* descriptor/object is in use */ 114 FDO_BUSY = 0x0001, /* descriptor/object is in use */
114 /* only used in individual stream descriptor */ 115 /* only used in individual stream descriptor */
115 FD_WRITE = 0x0002, /* descriptor has write mode */ 116 FD_WRITE = 0x0002, /* descriptor has write mode */
116 FD_WRONLY = 0x0004, /* descriptor is write mode only */ 117 FD_WRONLY = 0x0004, /* descriptor is write mode only */
117 FD_APPEND = 0x0008, /* descriptor is append mode */ 118 FD_APPEND = 0x0008, /* descriptor is append mode */
119 FD_NONEXIST = 0x8000, /* closed but not freed (uncombined) */
118 /* only used as common flags */ 120 /* only used as common flags */
119 FO_DIRECTORY = 0x0010, /* fileobj is a directory */ 121 FO_DIRECTORY = 0x0010, /* fileobj is a directory */
120 FO_TRUNC = 0x0020, /* fileobj is opened to be truncated */ 122 FO_TRUNC = 0x0020, /* fileobj is opened to be truncated */
121 FO_REMOVED = 0x0040, /* fileobj was deleted while open */ 123 FO_REMOVED = 0x0040, /* fileobj was deleted while open */
122 FO_SINGLE = 0x0080, /* fileobj has only one stream open */ 124 FO_SINGLE = 0x0080, /* fileobj has only one stream open */
123 FDO_MASK = 0x00ff, 125 FDO_MASK = 0x00ff,
124 /* bitflags that instruct various 'open' functions how to behave */ 126 FDO_CHG_MASK = FO_TRUNC, /* fileobj permitted external change */
125 FF_FILE = 0x0000, /* expect file; accept file only */ 127 /* bitflags that instruct various 'open' functions how to behave;
126 FF_DIR = 0x0100, /* expect dir; accept dir only */ 128 * saved in stream flags (only) but not used by manager */
127 FF_ANYTYPE = 0x0200, /* succeed if either file or dir */ 129 FF_FILE = 0x00000000, /* expect file; accept file only */
128 FF_TYPEMASK = 0x0300, /* mask of typeflags */ 130 FF_DIR = 0x00010000, /* expect dir; accept dir only */
129 FF_CREAT = 0x0400, /* create if file doesn't exist */ 131 FF_ANYTYPE = 0x00020000, /* succeed if either file or dir */
130 FF_EXCL = 0x0800, /* fail if creating and file exists */ 132 FF_TYPEMASK = 0x00030000, /* mask of typeflags */
131 FF_CHECKPREFIX = 0x1000, /* detect if file is prefix of path */ 133 FF_CREAT = 0x00040000, /* create if file doesn't exist */
132 FF_NOISO = 0x2000, /* do not decode ISO filenames to UTF-8 */ 134 FF_EXCL = 0x00080000, /* fail if creating and file exists */
133 FF_MASK = 0x3f00, 135 FF_CHECKPREFIX = 0x00100000, /* detect if file is prefix of path */
134 /* special values used in isolation */ 136 FF_NOISO = 0x00200000, /* do not decode ISO filenames to UTF-8 */
135 FV_NONEXIST = 0x8000, /* closed but not freed (unmounted) */ 137 FF_PROBE = 0x00400000, /* only test existence; don't open */
136 FV_OPENSYSROOT = 0xc001, /* open sysroot, volume 0 not mounted */ 138 FF_CACHEONLY = 0x00800000, /* succeed only if in dircache */
139 FF_SELFINFO = 0x01000000, /* return info on self as well */
140 FF_MASK = 0x01ff0000,
137}; 141};
138 142
139
140/** Common data structures used throughout **/ 143/** Common data structures used throughout **/
141 144
142/* basic file information about its location */ 145/* basic file information about its location */
@@ -183,8 +186,7 @@ struct dirscan_info
183struct filestr_base 186struct filestr_base
184{ 187{
185 struct ll_node node; /* list item node (first!) */ 188 struct ll_node node; /* list item node (first!) */
186 uint16_t flags; /* FD_* bits of this stream */ 189 uint32_t flags; /* F[DF]_* bits of this stream */
187 uint16_t unused; /* not used */
188 struct filestr_cache cache; /* stream-local cache */ 190 struct filestr_cache cache; /* stream-local cache */
189 struct filestr_cache *cachep; /* the cache in use (local or shared) */ 191 struct filestr_cache *cachep; /* the cache in use (local or shared) */
190 struct file_base_info *infop; /* base file information */ 192 struct file_base_info *infop; /* base file information */
@@ -235,17 +237,25 @@ static inline void filestr_unlock(struct filestr_base *stream)
235#define FILESTR_UNLOCK(type, stream) \ 237#define FILESTR_UNLOCK(type, stream) \
236 ({ if (FILESTR_##type) filestr_unlock(stream); }) 238 ({ if (FILESTR_##type) filestr_unlock(stream); })
237 239
238#define ATTR_PREFIX (0x8000) /* out of the way of all ATTR_* bits */ 240/* auxilliary attributes - out of the way of regular ATTR_* bits */
241#define ATTR_SYSROOT (0x8000)
242#define ATTR_PREFIX (0x4000)
239 243
240/* structure to return detailed information about what you opened */ 244/* structure to return detailed information about what you opened */
241struct path_component_info 245struct path_component_info
242{ 246{
243 const char *name; /* pointer to name within 'path' */ 247 const char *name; /* pointer to name within 'path' (OUT) */
244 size_t length; /* length of component within 'path' */ 248 size_t length; /* length of component within 'path' */
245 file_size_t filesize; /* size of the opened file (0 if dir) */ 249 file_size_t filesize; /* size of the opened file (0 if dir) */
246 unsigned int attr; /* attributes of this component */ 250 unsigned int attr; /* attributes of this component */
247 struct file_base_info *prefixp; /* base info to check as prefix (IN) */ 251 struct file_base_info *prefixp; /* base info to check as prefix
248 struct file_base_info parentinfo; /* parent directory info of file */ 252 (IN if FF_CHECKPREFIX) */
253 union {
254 struct file_base_info parentinfo; /* parent directory base info of file
255 (if not FF_SELFINFO) */
256 struct file_base_info info; /* base info of file itself
257 (if FF_SELFINFO) */
258 };
249}; 259};
250 260
251int open_stream_internal(const char *path, unsigned int callflags, 261int open_stream_internal(const char *path, unsigned int callflags,
@@ -261,6 +271,7 @@ int remove_stream_internal(const char *path, struct filestr_base *stream,
261int test_stream_exists_internal(const char *path, unsigned int callflags); 271int test_stream_exists_internal(const char *path, unsigned int callflags);
262 272
263int open_noiso_internal(const char *path, int oflag); /* file.c */ 273int open_noiso_internal(const char *path, int oflag); /* file.c */
274void force_close_writer_internal(struct filestr_base *stream); /* file.c */
264 275
265struct dirent; 276struct dirent;
266int uncached_readdir_dirent(struct filestr_base *stream, 277int uncached_readdir_dirent(struct filestr_base *stream,
@@ -326,22 +337,26 @@ static inline void file_internal_unlock_WRITER(void)
326 * not in the macro 337 * not in the macro
327 */ 338 */
328 339
340#define FILE_SET_CODE(_name, _keepcode, _value) \
341 ({ __builtin_constant_p(_value) ? \
342 ({ if ((_value) != (_keepcode)) _name = (_value); }) : \
343 ({ _name = (_value); }); })
344
329/* set errno and rc and proceed to the "file_error:" label */ 345/* set errno and rc and proceed to the "file_error:" label */
330#define FILE_ERROR(_errno, _rc) \ 346#define FILE_ERROR(_errno, _rc) \
331 ({ __builtin_constant_p(_errno) ? \ 347 ({ FILE_SET_CODE(errno, ERRNO, (_errno)); \
332 ({ if ((_errno) != ERRNO) errno = (_errno); }) : \ 348 FILE_SET_CODE(rc, RC, (_rc)); \
333 ({ errno = (_errno); }); \
334 __builtin_constant_p(_rc) ? \
335 ({ if ((_rc) != RC) rc = (_rc); }) : \
336 ({ rc = (_rc); }); \
337 goto file_error; }) 349 goto file_error; })
338 350
339/* set errno and return a value at the point of invocation */ 351/* set errno and return a value at the point of invocation */
340#define FILE_ERROR_RETURN(_errno, _rc...) \ 352#define FILE_ERROR_RETURN(_errno, _rc...) \
341 ({ __builtin_constant_p(_errno) ? \ 353 ({ FILE_SET_CODE(errno, ERRNO, _errno); \
342 ({ if ((_errno) != ERRNO) errno = (_errno); }) : \ 354 return _rc; })
343 ({ errno = (_errno); }); \ 355
344 return _rc; }) 356/* set errno and return code, no branching */
357#define FILE_ERROR_SET(_errno, _rc) \
358 ({ FILE_SET_CODE(errno, ERRNO, (_errno)); \
359 FILE_SET_CODE(rc, RC, (_rc)); })
345 360
346 361
347/** Misc. stuff **/ 362/** Misc. stuff **/
diff --git a/firmware/include/fileobj_mgr.h b/firmware/include/fileobj_mgr.h
index c90a59bea0..627d2df341 100644
--- a/firmware/include/fileobj_mgr.h
+++ b/firmware/include/fileobj_mgr.h
@@ -41,12 +41,11 @@ void fileobj_fileop_rename(struct filestr_base *stream,
41void fileobj_fileop_remove(struct filestr_base *stream, 41void fileobj_fileop_remove(struct filestr_base *stream,
42 const struct file_base_info *oldinfop); 42 const struct file_base_info *oldinfop);
43void fileobj_fileop_sync(struct filestr_base *stream); 43void fileobj_fileop_sync(struct filestr_base *stream);
44void fileobj_fileop_truncate(struct filestr_base *stream);
45extern void ftruncate_internal_callback(struct filestr_base *stream,
46 struct filestr_base *s);
47 44
48file_size_t * fileobj_get_sizep(const struct filestr_base *stream); 45file_size_t * fileobj_get_sizep(const struct filestr_base *stream);
49unsigned int fileobj_get_flags(const struct filestr_base *stream); 46unsigned int fileobj_get_flags(const struct filestr_base *stream);
47struct filestr_base * fileobj_get_next_stream(const struct filestr_base *stream,
48 const struct filestr_base *s);
50void fileobj_change_flags(struct filestr_base *stream, 49void fileobj_change_flags(struct filestr_base *stream,
51 unsigned int flags, unsigned int mask); 50 unsigned int flags, unsigned int mask);
52void fileobj_mgr_unmount(IF_MV_NONVOID(int volume)); 51void fileobj_mgr_unmount(IF_MV_NONVOID(int volume));