[PR #4621] Inode bug fix #4304

Open
opened 2026-04-25 00:19:12 +02:00 by adam · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/advplyr/audiobookshelf/pull/4621
Author: @jaxley
Created: 8/25/2025
Status: 🔄 Open

Base: masterHead: inode-bug-fix


📝 Commits (10+)

  • d8f07eb Fixed a few type issues
  • 3a4aacb Added deviceId in addition to inode to uniquely identify files
  • 974e17e Added additional unit tests for construction of objects containing deviceId property
  • ebdd554 Updated logic in compareUpdateLibraryFile
  • aae8085 Updated logic for checkAudioBookRemoved
  • 423f2d3 Added support for deviceId
  • 41a288b Added deviceId sequelize migration and completed unit tests
  • 5582a68 Populate deviceIds from disk
  • 925c8af Merge branch 'advplyr:master' into inode-bug-fix
  • 6b11da1 Updating next version number after latest release

📊 Changes

26 files changed (+2441 additions, -304 deletions)

View changed files

📝 .vscode/launch.json (+16 -19)
📝 package-lock.json (+837 -125)
📝 package.json (+2 -1)
📝 server/Watcher.js (+4 -4)
📝 server/managers/LogManager.js (+1 -1)
📝 server/migrations/changelog.md (+1 -0)
server/migrations/v2.30.0-add-deviceId.js (+193 -0)
📝 server/models/Book.js (+3 -1)
📝 server/models/LibraryItem.js (+9 -2)
📝 server/objects/Task.js (+1 -1)
📝 server/objects/files/AudioFile.js (+12 -5)
📝 server/objects/files/EBookFile.js (+11 -1)
📝 server/objects/files/LibraryFile.js (+19 -10)
📝 server/scanner/LibraryItemScanData.js (+77 -59)
📝 server/scanner/LibraryItemScanner.js (+30 -17)
📝 server/scanner/LibraryScanner.js (+84 -29)
📝 server/scanner/PodcastScanner.js (+1 -1)
📝 server/utils/fileUtils.js (+34 -8)
📝 server/utils/migrations/absMetadataMigration.js (+26 -19)
test/server/MockDatabase.js (+172 -0)

...and 6 more files

📄 Description

Brief summary

Which issue is fixed?

Fixes #1447

In-depth Description

This PR changes the database to store an additional foreign key, deviceId, that combined with inode (ino) uniquely identifies a file across linux filesystems. This resolves problems caused by duplicate inodes across different filesystems where the metadata and file associations get corrupted (see above issue).

I added a new column to the libraryItems table, deviceId. I also added an index to ensure the combination of ino + deviceId is distinct.

I changed the queries that just used inode to query also deviceId and I changed the fsUtils to return deviceId when getting file stats.

This was the simplest change that kept inode and deviceId distinct. I had considered concatenating inode and deviceId and storing in the existing ino field to achieve a single unique id, but that seems yucky.

Other changes

Along the way, I corrected various data type annotations that were incomplete or incorrect and added others to help identify problems and better understand the code and function arguments. e.g. several should have returned Promise but just returned foo.

I upgraded a couple unit testing libraries that were outdated. I have not upgraded others as that should be done via a separate PR - especially if any nuxt updates are breaking changes.

How have you tested this?

I created extensive unit tests for all changes and modified the code to be unit-testable to achieve the right amount of unit testability.

I also ran the server locally and uploaded several ebook files while debugging the flow and monitoring the logs. Scanned the library folder as well to verify that the files scanned properly.

Screenshots

N/A


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/advplyr/audiobookshelf/pull/4621 **Author:** [@jaxley](https://github.com/jaxley) **Created:** 8/25/2025 **Status:** 🔄 Open **Base:** `master` ← **Head:** `inode-bug-fix` --- ### 📝 Commits (10+) - [`d8f07eb`](https://github.com/advplyr/audiobookshelf/commit/d8f07eb956bb8ed9fb042b394d1cb0381e77a7aa) Fixed a few type issues - [`3a4aacb`](https://github.com/advplyr/audiobookshelf/commit/3a4aacb7bf85dc2d93b0fe748630c541c12e7762) Added deviceId in addition to inode to uniquely identify files - [`974e17e`](https://github.com/advplyr/audiobookshelf/commit/974e17ee3e84a6d4a9dd577455f33961c58d02e8) Added additional unit tests for construction of objects containing deviceId property - [`ebdd554`](https://github.com/advplyr/audiobookshelf/commit/ebdd5549bad41866c7418db7395276cc2fa82da0) Updated logic in compareUpdateLibraryFile - [`aae8085`](https://github.com/advplyr/audiobookshelf/commit/aae808544e686bb1e8ab49dee8f275b7a508df76) Updated logic for checkAudioBookRemoved - [`423f2d3`](https://github.com/advplyr/audiobookshelf/commit/423f2d311edf69d15ec9c265ef32b1b30d043899) Added support for deviceId - [`41a288b`](https://github.com/advplyr/audiobookshelf/commit/41a288bcdfa91c2e7e01ef934942a6e6b6383cbd) Added deviceId sequelize migration and completed unit tests - [`5582a68`](https://github.com/advplyr/audiobookshelf/commit/5582a685460dc8b32a1d475971a72023f3d0146b) Populate deviceIds from disk - [`925c8af`](https://github.com/advplyr/audiobookshelf/commit/925c8aff910eaa894fbfc047cf58be8f9450fa84) Merge branch 'advplyr:master' into inode-bug-fix - [`6b11da1`](https://github.com/advplyr/audiobookshelf/commit/6b11da158ee550d720c4aa9b657ffe7af5b1b6ed) Updating next version number after latest release ### 📊 Changes **26 files changed** (+2441 additions, -304 deletions) <details> <summary>View changed files</summary> 📝 `.vscode/launch.json` (+16 -19) 📝 `package-lock.json` (+837 -125) 📝 `package.json` (+2 -1) 📝 `server/Watcher.js` (+4 -4) 📝 `server/managers/LogManager.js` (+1 -1) 📝 `server/migrations/changelog.md` (+1 -0) ➕ `server/migrations/v2.30.0-add-deviceId.js` (+193 -0) 📝 `server/models/Book.js` (+3 -1) 📝 `server/models/LibraryItem.js` (+9 -2) 📝 `server/objects/Task.js` (+1 -1) 📝 `server/objects/files/AudioFile.js` (+12 -5) 📝 `server/objects/files/EBookFile.js` (+11 -1) 📝 `server/objects/files/LibraryFile.js` (+19 -10) 📝 `server/scanner/LibraryItemScanData.js` (+77 -59) 📝 `server/scanner/LibraryItemScanner.js` (+30 -17) 📝 `server/scanner/LibraryScanner.js` (+84 -29) 📝 `server/scanner/PodcastScanner.js` (+1 -1) 📝 `server/utils/fileUtils.js` (+34 -8) 📝 `server/utils/migrations/absMetadataMigration.js` (+26 -19) ➕ `test/server/MockDatabase.js` (+172 -0) _...and 6 more files_ </details> ### 📄 Description ## Brief summary <!-- Please provide a brief summary of what your PR attempts to achieve. --> ## Which issue is fixed? Fixes #1447 ## In-depth Description <!-- Describe your solution in more depth. How does it work? Why is this the best solution? Does it solve a problem that affects multiple users or is this an edge case for your setup? --> This PR changes the database to store an additional foreign key, deviceId, that combined with inode (ino) uniquely identifies a file across linux filesystems. This resolves problems caused by duplicate inodes across different filesystems where the metadata and file associations get corrupted (see above issue). I added a new column to the libraryItems table, deviceId. I also added an index to ensure the combination of ino + deviceId is distinct. I changed the queries that just used inode to query also deviceId and I changed the fsUtils to return deviceId when getting file stats. This was the simplest change that kept inode and deviceId distinct. I had considered concatenating inode and deviceId and storing in the existing ino field to achieve a single unique id, but that seems yucky. ### Other changes Along the way, I corrected various data type annotations that were incomplete or incorrect and added others to help identify problems and better understand the code and function arguments. e.g. several should have returned Promise<foo> but just returned foo. I upgraded a couple unit testing libraries that were outdated. I have not upgraded others as that should be done via a separate PR - especially if any nuxt updates are breaking changes. ## How have you tested this? I created extensive unit tests for all changes and modified the code to be unit-testable to achieve the right amount of unit testability. I also ran the server locally and uploaded several ebook files while debugging the flow and monitoring the logs. Scanned the library folder as well to verify that the files scanned properly. ## Screenshots N/A --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
adam added the pull-request label 2026-04-25 00:19:12 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/audiobookshelf#4304