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: <174786678247.1384866.5139178053250117853.stgit@frogsfrogsfrogs> Date: Wed, 21 May 2025 15:43:17 -0700 From: "Darrick J. Wong" <djwong@...nel.org> To: tytso@....edu Cc: linux-ext4@...r.kernel.org Subject: [PATCH 3/3] fuse2fs: implement blocksize converters From: Darrick J. Wong <djwong@...nel.org> Before we implement iomap, add some helpers to convert bytes to fsblocks and back. Signed-off-by: "Darrick J. Wong" <djwong@...nel.org> --- misc/fuse2fs.c | 92 ++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 66 insertions(+), 26 deletions(-) diff --git a/misc/fuse2fs.c b/misc/fuse2fs.c index a89ba115bf6f42..9c1e5b00703bbe 100644 --- a/misc/fuse2fs.c +++ b/misc/fuse2fs.c @@ -162,6 +162,9 @@ struct fuse2fs { uint8_t kernel; uint8_t directio; uint8_t acl; + + int blocklog; + unsigned int blockmask; unsigned long offset; unsigned int next_generation; unsigned long long cache_size; @@ -189,6 +192,39 @@ static int __translate_error(ext2_filsys fs, ext2_ino_t ino, errcode_t err, # define R_OK 4 #endif +static inline int u_log2(unsigned int arg) +{ + int l = 0; + + arg >>= 1; + while (arg) { + l++; + arg >>= 1; + } + return l; +} + +static inline blk64_t FUSE2FS_B_TO_FSBT(const struct fuse2fs *ff, off_t pos) +{ + return pos >> ff->blocklog; +} + +static inline blk64_t FUSE2FS_B_TO_FSB(const struct fuse2fs *ff, off_t pos) +{ + return (pos + ff->blockmask) >> ff->blocklog; +} + +static inline unsigned int FUSE2FS_OFF_IN_FSB(const struct fuse2fs *ff, + off_t pos) +{ + return pos & ff->blockmask; +} + +static inline off_t FUSE2FS_FSB_TO_B(const struct fuse2fs *ff, blk64_t bno) +{ + return bno << ff->blocklog; +} + #define EXT4_EPOCH_BITS 2 #define EXT4_EPOCH_MASK ((1 << EXT4_EPOCH_BITS) - 1) #define EXT4_NSEC_MASK (~0UL << EXT4_EPOCH_BITS) @@ -2223,7 +2259,7 @@ static int punch_posteof(struct fuse2fs *ff, ext2_ino_t ino, off_t new_size) { ext2_filsys fs = ff->fs; struct ext2_inode_large inode; - blk64_t truncate_block = (new_size + fs->blocksize - 1) / fs->blocksize; + blk64_t truncate_block = FUSE2FS_B_TO_FSB(ff, new_size); errcode_t err; err = fuse2fs_read_inode(fs, ino, &inode); @@ -2525,7 +2561,7 @@ static int op_write(const char *path EXT2FS_ATTR((unused)), goto out; } - if (!fs_can_allocate(ff, len / fs->blocksize)) { + if (!fs_can_allocate(ff, FUSE2FS_B_TO_FSB(ff, len))) { ret = -ENOSPC; goto out; } @@ -3684,9 +3720,9 @@ static int ioctl_fitrim(struct fuse2fs *ff, struct fuse2fs_file_handle *fh, if (!fs_writeable(fs)) return -EROFS; - start = fr->start / fs->blocksize; - end = (fr->start + fr->len - 1) / fs->blocksize; - minlen = fr->minlen / fs->blocksize; + start = FUSE2FS_B_TO_FSBT(ff, fr->start); + end = FUSE2FS_B_TO_FSBT(ff, fr->start + fr->len - 1); + minlen = FUSE2FS_B_TO_FSBT(ff, fr->minlen); if (EXT2FS_NUM_B2C(fs, minlen) > EXT2_CLUSTERS_PER_GROUP(fs->super) || start >= max_blks || @@ -3705,7 +3741,7 @@ static int ioctl_fitrim(struct fuse2fs *ff, struct fuse2fs_file_handle *fh, end = ext2fs_blocks_count(fs->super) - 1; cleared = 0; - max_blocks = 2048ULL * 1024 * 1024 / fs->blocksize; + max_blocks = FUSE2FS_B_TO_FSBT(ff, 2048ULL * 1024 * 1024); fr->len = 0; while (start <= end) { @@ -3732,7 +3768,7 @@ static int ioctl_fitrim(struct fuse2fs *ff, struct fuse2fs_file_handle *fh, if (err) return translate_error(fs, fh->ino, err); cleared += b - start; - fr->len = cleared * fs->blocksize; + fr->len = FUSE2FS_FSB_TO_B(ff, cleared); } start = b + 1; } @@ -3850,11 +3886,11 @@ static int fallocate_helper(struct fuse_file_info *fp, int mode, off_t offset, FUSE2FS_CHECK_CONTEXT(ff); fs = ff->fs; FUSE2FS_CHECK_MAGIC(fs, fh, FUSE2FS_FILE_MAGIC); - start = offset / fs->blocksize; - end = (offset + len - 1) / fs->blocksize; - dbg_printf(ff, "%s: ino=%d mode=0x%x start=%jd end=%llu\n", __func__, - fh->ino, mode, offset / fs->blocksize, end); - if (!fs_can_allocate(ff, len / fs->blocksize)) + start = FUSE2FS_B_TO_FSBT(ff, offset); + end = FUSE2FS_B_TO_FSBT(ff, offset + len - 1); + dbg_printf(ff, "%s: ino=%d mode=0x%x start=%llu end=%llu\n", __func__, + fh->ino, mode, start, end); + if (!fs_can_allocate(ff, FUSE2FS_B_TO_FSB(ff, len))) return -ENOSPC; err = fuse2fs_read_inode(fs, fh->ino, &inode); @@ -3893,16 +3929,17 @@ static int fallocate_helper(struct fuse_file_info *fp, int mode, off_t offset, return err; } -static errcode_t clean_block_middle(ext2_filsys fs, ext2_ino_t ino, - struct ext2_inode_large *inode, off_t offset, - off_t len, char **buf) +static errcode_t clean_block_middle(struct fuse2fs *ff, ext2_ino_t ino, + struct ext2_inode_large *inode, + off_t offset, off_t len, char **buf) { + ext2_filsys fs = ff->fs; blk64_t blk; off_t residue; int retflags; errcode_t err; - residue = offset % fs->blocksize; + residue = FUSE2FS_OFF_IN_FSB(ff, offset); if (residue == 0) return 0; @@ -3913,7 +3950,7 @@ static errcode_t clean_block_middle(ext2_filsys fs, ext2_ino_t ino, } err = ext2fs_bmap2(fs, ino, EXT2_INODE(inode), *buf, 0, - offset / fs->blocksize, &retflags, &blk); + FUSE2FS_B_TO_FSBT(ff, offset), &retflags, &blk); if (err) return err; if (!blk || (retflags & BMAP_RET_UNINIT)) @@ -3928,16 +3965,17 @@ static errcode_t clean_block_middle(ext2_filsys fs, ext2_ino_t ino, return io_channel_write_blk(fs->io, blk, 1, *buf); } -static errcode_t clean_block_edge(ext2_filsys fs, ext2_ino_t ino, +static errcode_t clean_block_edge(struct fuse2fs *ff, ext2_ino_t ino, struct ext2_inode_large *inode, off_t offset, int clean_before, char **buf) { + ext2_filsys fs = ff->fs; blk64_t blk; int retflags; off_t residue; errcode_t err; - residue = offset % fs->blocksize; + residue = FUSE2FS_OFF_IN_FSB(ff, offset); if (residue == 0) return 0; @@ -3948,7 +3986,7 @@ static errcode_t clean_block_edge(ext2_filsys fs, ext2_ino_t ino, } err = ext2fs_bmap2(fs, ino, EXT2_INODE(inode), *buf, 0, - offset / fs->blocksize, &retflags, &blk); + FUSE2FS_B_TO_FSBT(ff, offset), &retflags, &blk); if (err) return err; @@ -3989,7 +4027,7 @@ static int punch_helper(struct fuse_file_info *fp, int mode, off_t offset, return -EINVAL; /* Punch out a bunch of blocks */ - start = (offset + fs->blocksize - 1) / fs->blocksize; + start = FUSE2FS_B_TO_FSB(ff, offset); end = (offset + len - fs->blocksize) / fs->blocksize; dbg_printf(ff, "%s: ino=%d mode=0x%x start=%llu end=%llu\n", __func__, fh->ino, mode, start, end); @@ -3999,13 +4037,13 @@ static int punch_helper(struct fuse_file_info *fp, int mode, off_t offset, return translate_error(fs, fh->ino, err); /* Zero everything before the first block and after the last block */ - if ((offset / fs->blocksize) == ((offset + len) / fs->blocksize)) - err = clean_block_middle(fs, fh->ino, &inode, offset, + if (FUSE2FS_B_TO_FSBT(ff, offset) == FUSE2FS_B_TO_FSBT(ff, offset + len)) + err = clean_block_middle(ff, fh->ino, &inode, offset, len, &buf); else { - err = clean_block_edge(fs, fh->ino, &inode, offset, 0, &buf); + err = clean_block_edge(ff, fh->ino, &inode, offset, 0, &buf); if (!err) - err = clean_block_edge(fs, fh->ino, &inode, + err = clean_block_edge(ff, fh->ino, &inode, offset + len, 1, &buf); } if (buf) @@ -4379,6 +4417,8 @@ int main(int argc, char *argv[]) } fctx.fs = global_fs; global_fs->priv_data = &fctx; + fctx.blocklog = u_log2(fctx.fs->blocksize); + fctx.blockmask = fctx.fs->blocksize - 1; if (!fctx.cache_size) fctx.cache_size = default_cache_size(); @@ -4386,7 +4426,7 @@ int main(int argc, char *argv[]) char buf[55]; snprintf(buf, sizeof(buf), "cache_blocks=%llu", - fctx.cache_size / global_fs->blocksize); + FUSE2FS_B_TO_FSBT(&fctx, fctx.cache_size)); err = io_channel_set_options(global_fs->io, buf); if (err) { err_printf(&fctx, "%s %lluk: %s\n",
Powered by blists - more mailing lists