diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2017-01-08 17:14:10 -0500 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2017-01-17 14:35:36 -0500 |
commit | a931c76b3a46d1884e985a3bfc82b947521dab97 (patch) | |
tree | 1141cf9a9a8c123bde3d76d147ee1e910c7c6045 /firmware/common/file_internal.c | |
parent | 0056ea8a256af0e2daaf451af43c00708a31d4df (diff) | |
download | rockbox-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.c | 48 |
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 | |||
641 | file_error: | 660 | file_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 | } |