summaryrefslogtreecommitdiff
path: root/firmware/common/file_internal.c
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/common/file_internal.c
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/common/file_internal.c')
-rw-r--r--firmware/common/file_internal.c48
1 files changed, 34 insertions, 14 deletions
diff --git a/firmware/common/file_internal.c b/firmware/common/file_internal.c
index f9c6bfb570..aa0edb7ebb 100644
--- a/firmware/common/file_internal.c
+++ b/firmware/common/file_internal.c
@@ -292,7 +292,7 @@ struct pathwalk_component
292 struct pathwalk_component *nextp; /* parent if in use else next free */ 292 struct pathwalk_component *nextp; /* parent if in use else next free */
293}; 293};
294 294
295#define WALK_RC_NOT_FOUND 0 /* successfully not found */ 295#define WALK_RC_NOT_FOUND 0 /* successfully not found (aid for file creation) */
296#define WALK_RC_FOUND 1 /* found and opened */ 296#define WALK_RC_FOUND 1 /* found and opened */
297#define WALK_RC_FOUND_ROOT 2 /* found and opened sys/volume root */ 297#define WALK_RC_FOUND_ROOT 2 /* found and opened sys/volume root */
298#define WALK_RC_CONT_AT_ROOT 3 /* continue at root level */ 298#define WALK_RC_CONT_AT_ROOT 3 /* continue at root level */
@@ -351,7 +351,10 @@ static int fill_path_compinfo(struct pathwalk *walkp,
351 compinfo->length = compp->length; 351 compinfo->length = compp->length;
352 compinfo->attr = compp->attr; 352 compinfo->attr = compp->attr;
353 compinfo->filesize = walkp->filesize; 353 compinfo->filesize = walkp->filesize;
354 compinfo->parentinfo = (compp->nextp ?: compp)->info; 354 if (!(walkp->callflags & FF_SELFINFO))
355 compinfo->parentinfo = (compp->nextp ?: compp)->info;
356 else
357 compinfo->info = compp->info;
355 } 358 }
356 359
357 return rc; 360 return rc;
@@ -393,7 +396,10 @@ static int walk_open_info(struct pathwalk *walkp,
393 else 396 else
394 callflags &= ~FO_DIRECTORY; 397 callflags &= ~FO_DIRECTORY;
395 398
396 fileop_onopen_internal(stream, &compp->info, callflags); 399 /* make open official if not simply probing for presence */
400 if (!(callflags & FF_PROBE))
401 fileop_onopen_internal(stream, &compp->info, callflags);
402
397 return compp->nextp ? WALK_RC_FOUND : WALK_RC_FOUND_ROOT; 403 return compp->nextp ? WALK_RC_FOUND : WALK_RC_FOUND_ROOT;
398} 404}
399 405
@@ -511,7 +517,8 @@ walk_path(struct pathwalk *walkp, struct pathwalk_component *compp,
511 { 517 {
512 /* is ".." */ 518 /* is ".." */
513 struct pathwalk_component *parentp = compp->nextp; 519 struct pathwalk_component *parentp = compp->nextp;
514 if (!parentp) 520
521 if (!parentp IF_MV( || parentp->attr == ATTR_SYSTEM_ROOT ))
515 return WALK_RC_CONT_AT_ROOT; 522 return WALK_RC_CONT_AT_ROOT;
516 523
517 compp->nextp = freep; 524 compp->nextp = freep;
@@ -567,6 +574,9 @@ int open_stream_internal(const char *path, unsigned int callflags,
567 if (!compinfo) 574 if (!compinfo)
568 callflags &= ~FF_CHECKPREFIX; 575 callflags &= ~FF_CHECKPREFIX;
569 576
577 /* This lets it be passed quietly to directory scanning */
578 stream->flags = callflags & FF_MASK;
579
570 struct pathwalk walk; 580 struct pathwalk walk;
571 walk.path = path; 581 walk.path = path;
572 walk.callflags = callflags; 582 walk.callflags = callflags;
@@ -575,7 +585,7 @@ int open_stream_internal(const char *path, unsigned int callflags,
575 585
576 struct pathwalk_component *rootp = pathwalk_comp_alloc(NULL); 586 struct pathwalk_component *rootp = pathwalk_comp_alloc(NULL);
577 rootp->nextp = NULL; 587 rootp->nextp = NULL;
578 rootp->attr = ATTR_DIRECTORY; 588 rootp->attr = ATTR_SYSTEM_ROOT;
579 589
580#ifdef HAVE_MULTIVOLUME 590#ifdef HAVE_MULTIVOLUME
581 int volume = 0, rootrc = WALK_RC_FOUND; 591 int volume = 0, rootrc = WALK_RC_FOUND;
@@ -584,7 +594,7 @@ int open_stream_internal(const char *path, unsigned int callflags,
584 while (1) 594 while (1)
585 { 595 {
586 const char *pathptr = walk.path; 596 const char *pathptr = walk.path;
587 597
588 #ifdef HAVE_MULTIVOLUME 598 #ifdef HAVE_MULTIVOLUME
589 /* this seamlessly integrates secondary filesystems into the 599 /* this seamlessly integrates secondary filesystems into the
590 root namespace (e.g. "/<0>/../../<1>/../foo/." :<=> "/foo") */ 600 root namespace (e.g. "/<0>/../../<1>/../foo/." :<=> "/foo") */
@@ -596,8 +606,19 @@ int open_stream_internal(const char *path, unsigned int callflags,
596 FILE_ERROR(ENXIO, -2); 606 FILE_ERROR(ENXIO, -2);
597 } 607 }
598 608
599 /* the root of this subpath is the system root? */ 609 if (p == pathptr)
600 rootrc = p == pathptr ? WALK_RC_FOUND_ROOT : WALK_RC_FOUND; 610 {
611 /* the root of this subpath is the system root */
612 rootp->attr = ATTR_SYSTEM_ROOT;
613 rootrc = WALK_RC_FOUND_ROOT;
614 }
615 else
616 {
617 /* this subpath specifies a mount point */
618 rootp->attr = ATTR_MOUNT_POINT;
619 rootrc = WALK_RC_FOUND;
620 }
621
601 walk.path = p; 622 walk.path = p;
602 #endif /* HAVE_MULTIVOLUME */ 623 #endif /* HAVE_MULTIVOLUME */
603 624
@@ -633,11 +654,9 @@ int open_stream_internal(const char *path, unsigned int callflags,
633 default: /* utter, abject failure :`( */ 654 default: /* utter, abject failure :`( */
634 DEBUGF("Open failed: rc=%d, errno=%d\n", rc, errno); 655 DEBUGF("Open failed: rc=%d, errno=%d\n", rc, errno);
635 filestr_base_destroy(stream); 656 filestr_base_destroy(stream);
636 FILE_ERROR(-rc, -2); 657 FILE_ERROR(-rc, -3);
637 } 658 }
638 659
639 file_cache_reset(stream->cachep);
640
641file_error: 660file_error:
642 return rc; 661 return rc;
643} 662}
@@ -757,9 +776,10 @@ int test_stream_exists_internal(const char *path, unsigned int callflags)
757{ 776{
758 /* only FF_* flags should be in callflags */ 777 /* only FF_* flags should be in callflags */
759 struct filestr_base stream; 778 struct filestr_base stream;
760 int rc = open_stream_internal(path, callflags, &stream, NULL); 779 int rc = open_stream_internal(path, callflags | FF_PROBE, &stream, NULL);
761 if (rc > 0) 780
762 close_stream_internal(&stream); 781 if (rc >= 0)
782 filestr_base_destroy(&stream);
763 783
764 return rc; 784 return rc;
765} 785}