Dear f2fs Development Community, This thread is initiated to discuss the challenge of integrating iomap_folio_state (hereafter referred to as ifs) into f2fs pointed out by Mr. Matthew in this email: https://lore.kernel.org/linux-f2fs-devel/camlch1eosva1as4vdbcpsh75apfmknofhihorxvommz-+mu...@mail.gmail.com/T/#t
> The challenge with that is that iomap does not support all the > functionality that f2fs requires. The iomap data structure could > be duplicated inside f2fs, but then we hit the problem that f2fs > currently stores other information in folio->private. So we'd need > to add a flags field to iomap_folio_state to store that information > instead. To address this, I have designed a custom structure for f2fs, aiming to minimize modifications to existing iomap functionalities and data structures. The proposed structure, named f2fs_iomap_folio_state (hereafter referred to as f2fs_ifs), is defined as follows: f2fs_iomap_folio_state { struct iomap_folio_state ifs; unsigned int magic_number; unsigned int private; // for f2fs page private flags } The f2fs_ifs structure embeds the standard ifs structure at the beginning of its definition. This ensures that the initial memory layout of f2fs_ifs is identical to ifs, thereby maintaining compatibility with a wide range of iomap APIs (excluding ifs_alloc and ifs_free). Importantly, calling ifs_alloc on a folio whose folio->private already points to an f2fs_ifs structure will not result in errors. This is because ifs_alloc is designed to return the existing pointer if folio->private is not NULL. My original purpose behind this design is to preserve the integrity of native iomap functions and data structures as much as possible. The level of customization currently provided by iomap functions for file systems appears to be insufficient for f2fs's requirements. For example, the iomap_readahead function's iomap_readpage_iter internally and inflexibly calls APIs like ifs_alloc. Currently, there are two key technical details that require careful consideration: Distinguishing between ifs and f2fs_ifs: A significant challenge is reliably differentiating whether a given folio->private pointer points to a standard ifs or our custom f2fs_ifs structure. This is a headache as it involves runtime type identification from a void*, which cannot be resolved through compile-time type checking. To mitigate this, I have introduced a magic_number field within f2fs_ifs. The proposed approach is to cast folio->private to f2fs_ifs, calculate an offset based on the size of the ifs structure (which is dynamically determined by the folio's block count due to the variable-sized state bitmap in ifs), and then check if the value at the magic_number field matches a pre-defined magic value. If a match is found, we infer that it is an f2fs_ifs. However, this approach is not without risk. In the scenario where folio->private points to a regular ifs, and by a little chance, the value at the calculated offset within the ifs structure happens to coincide with our chosen magic number, the check would incorrectly identify it as f2fs_ifs. This could potentially lead to undefined behavior. I am actively seeking more robust solutions for this type identification problem and would greatly appreciate any suggestions or alternative approaches the community might offer. Allocation Timing of f2fs_ifs: Another crucial aspect is determining the optimal timing for allocating f2fs_ifs. My current thinking is that allocating it during the readahead process might be advantageous. At this stage, the folio is under lock protection, ensuring thread safety. Furthermore, allocating f2fs_ifs during readahead could ideally ensure that the private field of all folios within the page cache consistently points to f2fs_ifs.I belive this will bring a lot of convenience. The implementation may be a bit tricky. If we intend to leverage iomap_readahead to provide an iomap-based readahead function for f2fs, custom iomap_begin and iomap_end operations will not suffice for allocating f2fs_ifs. This limitation arises because these functions do not have access to the necessary readahead_control and iomap_readpage_ctx structures, and consequently, cannot directly access the folio. My current proposed solution is as follows: f2fs_iomap_readahead(readahead_control* rac) { struct readahead_control rac_cp = copy_rac(rac); struct folio* folio; while (folio = readahead_folio(rac_cp)) { f2fs_ifs_alloc(folio); } iomap_readahead(rac, &f2fs_buffered_read_iomap_ops); } Alternatively, we could consider duplicating the iomap_readahead function within f2fs and making the necessary modifications directly within the duplicated code. I would greatly appreciate any feedback, insights, and suggestions from the community regarding these technical details and the overall approach. Your expertise and perspectives are invaluable as we work towards a robust and efficient integration of iomap_folio_state into f2fs. Thank you for your time and consideration. _______________________________________________ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel