summaryrefslogtreecommitdiff
path: root/firmware/include/file_internal.h
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2017-01-08 17:14:10 -0500
committerMichael Sevakis <jethead71@rockbox.org>2017-01-17 14:35:36 -0500
commita931c76b3a46d1884e985a3bfc82b947521dab97 (patch)
tree1141cf9a9a8c123bde3d76d147ee1e910c7c6045 /firmware/include/file_internal.h
parent0056ea8a256af0e2daaf451af43c00708a31d4df (diff)
downloadrockbox-a931c76b3a46d1884e985a3bfc82b947521dab97.tar.gz
rockbox-a931c76b3a46d1884e985a3bfc82b947521dab97.zip
Do some debug and preparatory work for ramcache and playlist
The file system rework introduced incompatibility between dircache and the tagcache ramcache and playlist dircache path caching. This update makes changes to filesystem code to reintegrate all that. It also fixes a couple bugs that were found when vetting all the code. The filestream cache was being reset without regard to the stream even if it was shared in write mode (made work of .playlist_control). Better handling of unmounting gives files a better go at force-closing them without risk to disk integrity. Did some miscellaneous pedantic changes. Improved efficiency of testing a file's existence (a little) since the path parser will be shared between file code and parsing for the sake of finding dircache references, not duplicated as before. This commit doesn't reenable said items just for the sake of keeping changes separate and related. Plan for the next is to enable dircache again for the playlists (easy peasy) and reenable tagcache ramcache but *without* the dircache path caching because it's rather substantial to change in itself. The ramcache will still function without dircache. Change-Id: I7e2a9910b866251fa8333e1275f72fcfc8425d2d
Diffstat (limited to 'firmware/include/file_internal.h')
-rw-r--r--firmware/include/file_internal.h91
1 files changed, 53 insertions, 38 deletions
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 **/