On Mon, Jul 28, 2025 at 10:55:42AM -0700, Joanne Koong wrote:
On Mon, Jul 28, 2025 at 10:34 AM Matthew Wilcox willy@infradead.org wrote:
On Fri, Jul 25, 2025 at 06:16:15PM -0700, Joanne Koong wrote:
> Also, I just noticed that apparently the blocksize can change > dynamically for an inode in fuse through getattr replies from the > server (see fuse_change_attributes_common()). This is a problem since > the iomap uses inode->i_blkbits for reading/writing to the bitmap. I > think we will have to cache the inode blkbits in the iomap_folio_state > struct unfortunately :( I'll think about this some more and send out a > patch for this.
Does this actually happen in practice, once you've started _using_ the block device? Rather than all this complicated stuff to invalidate the
For most block device filesystems? No. And as far as I can tell, none of the filesystems actually support changing i_blkbits on the fly; I think only block devices can do that:
$ git grep 'i_blkbits\s=\s' block/bdev.c:150: BD_INODE(bdev)->i_blkbits = blksize_bits(bsize); block/bdev.c:209: inode->i_blkbits = blksize_bits(size); fs/ceph/inode.c:81: inode->i_blkbits = CEPH_FSCRYPT_BLOCK_SHIFT; fs/ceph/inode.c:1071: inode->i_blkbits = CEPH_FSCRYPT_BLOCK_SHIFT; fs/ceph/inode.c:1076: inode->i_blkbits = CEPH_BLOCK_SHIFT; fs/ceph/inode.c:1180: inode->i_blkbits = PAGE_SHIFT; fs/direct-io.c:612: unsigned int i_blkbits = sdio->blkbits + sdio->blkfactor; fs/direct-io.c:908: const unsigned i_blkbits = blkbits + sdio->blkfactor; fs/direct-io.c:1110: unsigned i_blkbits = READ_ONCE(inode->i_blkbits); fs/erofs/fscache.c:527: inode->i_blkbits = EROFS_SB(sb)->blkszbits; fs/fuse/file_iomap.c:2327: inode->i_blkbits = new_blkbits; fs/fuse/inode.c:304: inode->i_blkbits = new_blkbits; fs/inode.c:234: inode->i_blkbits = sb->s_blocksize_bits; fs/libfs.c:1761: inode->i_blkbits = PAGE_SHIFT; fs/ocfs2/aops.c:2123: unsigned int i_blkbits = inode->i_sb->s_blocksize_bits; fs/orangefs/orangefs-utils.c:320: inode->i_blkbits = ffs(new_op->downcall.resp.getattr. fs/smb/client/cifsfs.c:411: cifs_inode->netfs.inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */ fs/stack.c:72: dest->i_blkbits = src->i_blkbits; fs/vboxsf/utils.c:123: inode->i_blkbits = 12;
page cache based on the fuse server telling us something, maybe just declare the server to be misbehaving and shut the whole filesystem down?
I don't think this case is likely at all but I guess one scenario where the server might want to change the block size midway through is if they send the data to some network filesystem on the backend and if that backend shuts down or is at full capacity for whatever reason and they need to migrate to another backend that uses a different block size then I guess this would be useful for that.
Maybe, but it would still be pretty extraordinary to change the block size on an open file -- any program that tries to do its IO in blocks (i.e. not a byte stream) has already stat'd the file and will be very confused.
fuse currently does allow the block size to be changed dynamically so I'm not sure if we can change that behavior without breaking backwards compatibility.
<nod> For fuse+iomap I'm not going to allow it initially if there's anything in the pagecache ... but I could be talked into it.
--D