Skip to content

fix(posix): don't inflate tree sizes when assimilating a file fails - #797

Open
NickWalters wants to merge 1 commit into
opencloud-eu:mainfrom
NickWalters:fix/posix-propagate-after-set
Open

fix(posix): don't inflate tree sizes when assimilating a file fails#797
NickWalters wants to merge 1 commit into
opencloud-eu:mainfrom
NickWalters:fix/posix-propagate-after-set

Conversation

@NickWalters

Copy link
Copy Markdown

In updateFile a file's size is propagated to its parent directories before the file's own attributes are written. If writing the attributes fails, the parents have already been updated but the file still has no blobsize. The next attempt sees a previous size of 0 and propagates the whole size again, so every failed attempt inflates the tree size of every parent directory by the size of the file.

I ran into this while looking into opencloud-eu/opencloud#3498, where files couldn't be assimilated because the opencloud user had no write permission on them. They were retried over and over, and I think this is why the space root ended up claiming 6.3 TB and a 52 GB copy showed up as 70 GB. The sizes only went back to normal after a restart, when the initial scan recalculated them.

This moves the propagation after the attributes are stored, which is the order TouchFile and Move in the posix tree already use. The downside is the same as there: if propagating fails after the attributes are written, a retry won't propagate the size again. The next scan of that directory sets its tree size from what's on disk, so it sorts itself out.

The new spec in tree_non_watching_test.go lists a folder with a read-only file in it and checks that the folder's tree size is still 0 afterwards. It fails on main (12) and passes with this change. It skips as root, since root can set xattrs on read-only files. go test -race ./pkg/storage/fs/posix/... passes locally and golangci-lint is clean on the package.

This is separate from #796, which stops those files from being retried constantly in the first place. The two don't depend on each other and merge cleanly in either order.

updateFile propagated a file's size to its parents before writing the
file's attributes. When writing them failed, the file still had no
blobsize, so the next attempt propagated the whole size again and every
failed attempt inflated the tree sizes of all parent directories.

Propagate only once the attributes are stored, like TouchFile and Move
already do.

Refs opencloud-eu/opencloud#3498
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.

1 participant