Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix SD info64 : info.usedBytes calculation giving weird result #8445

Merged
merged 1 commit into from
Jan 10, 2022

Conversation

luc-github
Copy link
Contributor

No description provided.

@@ -101,7 +101,7 @@ class SDFSImpl : public FSImpl
info.pageSize = 0; // TODO ?
info.maxPathLength = 255; // TODO ?
info.totalBytes =_fs.vol()->clusterCount() * info.blockSize;
info.usedBytes = info.totalBytes - (_fs.vol()->freeClusterCount() * _fs.vol()->bytesPerCluster());
info.usedBytes = (_fs.vol()->clusterCount() - _fs.vol()->freeClusterCount()) * info.blockSize;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I manually factor things I think this change is mathematically the same as the existing code.

info.usedBytes = info.totalBytes - (_fs.vol()->freeClusterCount() * _fs.vol()->bytesPerCluster());
info.totalBytes =_fs.vol()->clusterCount() * info.blockSize;
info.blockSize = _fs.vol()->bytesPerCluster();

So,

info.usedBytes = (_fs.vol()->clusterCount() * _fs.vol()->bytesPerCluster()) - (_fs.vol()->freeClusterCount() * _fs.vol()->bytesPerCluster());

Factor out the bpc and you get

info.usedBytes = (_fs.vol()->clusterCount() - _fs.vol()->freeClusterCount() ) * _fs.vol()->bytesPerCluster();

which is the patch's rewrite, no?

Copy link
Contributor Author

@luc-github luc-github Jan 9, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do agree about calculation , but the fact is the current does not give the correct result.
Seems overflow happen.

Could be a type issue when doing calculation ?

Copy link
Contributor Author

@luc-github luc-github Jan 9, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with figures it is may be more clear:

#include <SPI.h>
#include <SD.h>
#include <SDFS.h>
void setup(){
    Serial.begin(115200);
    if(!SD.begin(5)){
        Serial.println("Card Mount Failed");
        return;
    }
	FSInfo64 info;
	 if (!SDFS.info64(info)) {
		 Serial.println("Size unkown");
            return ;
        }
    Serial.printf("\nTotal space: %lluMB\n", info.totalBytes / (1024 * 1024));
    Serial.printf("Used space: %lluMB\n", info.usedBytes / (1024 * 1024));
}

void loop(){}

Without PR
Total space: 3760MB
Used space: 4929MB =>Wrong

With PR
Total space: 3760MB
Used space: 833MB =>Correct

Copy link
Collaborator

@earlephilhower earlephilhower left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for giving the example. You're probably right, there is some type promotion issue and 32b overflow in the existing code.

@earlephilhower earlephilhower merged commit 2c5885e into esp8266:master Jan 10, 2022
@mcspr
Copy link
Collaborator

mcspr commented Jan 10, 2022

Maybe we would want explicit casts to u64? There are mixed i32, u16 and u32, while we expect the result to be u64-wide and not u32 cast into one in the end
Plus, freeClusterCount() may return -1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants