lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Message-ID: <87jznyr6xd.fsf@suse.de> Date: Wed, 24 Jan 2024 17:13:18 +0000 From: Luis Henriques <lhenriques@...e.de> To: Daniel Dawson <danielcdawson@...il.com> Cc: Theodore Ts'o <tytso@....edu>, Andreas Dilger <adilger.kernel@...ger.ca>, linux-ext4@...r.kernel.org, linux-kernel@...r.kernel.org Subject: Re: [inline_data] ext4: Stale flags before sync when convert to non-inline Daniel Dawson <danielcdawson@...il.com> writes: > On 11/28/23 10:15 PM, Daniel Dawson wrote: >> When a file is converted from inline to non-inline, it has stale flags until >> sync. > >> Why is this a problem? Because some code will fail under such a condition, for >> example, lseek(..., SEEK_HOLE) will result in ENOENT. > > > Just tested. Still happening on 6.8-rc1. FWIW, I've been looking into a similar issue related with inline-data and delayed allocation. It may however be quite different because it seems to add small block sizes into the mix: https://bugzilla.kernel.org/show_bug.cgi?id=200681 Unfortunately, I'm still trying to find my way around all this code and I can't say I fully understand the whole flow using the reproducer provided in that bugzilla. Bellow, I'm inlining a patch that started as debug patch that I've used to try to understand what was going on. It seems to workaround that bug, but I know it's not a real fix -- I don't yet understand what's going on. Regarding your specific usecase, I can reproduce it and, unfortunately, I don't thing Ted's suggestion will fix it as I don't even see ext4_iomap_begin_report() being executed at all. Anyway, just my 2 cents... let's see if I can come up with something. Cheers, -- Luís diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c index d5bd1e3a5d36..d0c3d6fd48de 100644 --- a/fs/ext4/inline.c +++ b/fs/ext4/inline.c @@ -528,7 +528,19 @@ int ext4_readpage_inline(struct inode *inode, struct folio *folio) if (!folio->index) ret = ext4_read_inline_folio(inode, folio); else if (!folio_test_uptodate(folio)) { - folio_zero_segment(folio, 0, folio_size(folio)); + struct buffer_head *bh, *head; + size_t start = 0; + + head = folio_buffers(folio); + if (head) { + bh = head; + do { + if (!buffer_uptodate(bh)) + break; + start += inode->i_sb->s_blocksize; + } while ((bh = bh->b_this_page) != head); + } + folio_zero_segment(folio, start, folio_size(folio)); folio_mark_uptodate(folio); }
Powered by blists - more mailing lists