mirror of
https://github.com/versity/scoutfs.git
synced 2026-01-10 05:37:25 +00:00
scoutfs: track inode 512b block count
We weren't doing anything with the inode blocks field. We weren't even initializing it which explains why we'd sometimes see garbage i_blocks values in scoutfs inodes in segments. The logical blocks field reflects the contents of the file regardless of whether its online or not. It's the sum of our online and offline block tracking. So we can initialize it to our persistent online and offline counts and then keep it in sync as blocks are allocated and freed. Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
@@ -692,15 +692,19 @@ int scoutfs_data_truncate_items(struct super_block *sb, struct inode *inode,
|
||||
|
||||
map->blknos[i] = 0;
|
||||
scoutfs_inode_add_online_blocks(inode, -1);
|
||||
/* XXX gets tricky with concurrent writes */
|
||||
inode->i_blocks -= SCOUTFS_BLOCK_SECTORS;
|
||||
}
|
||||
|
||||
if (offline && !test_bit(i, map->offline)) {
|
||||
set_bit(i, map->offline);
|
||||
scoutfs_inode_add_offline_blocks(inode, 1);
|
||||
inode->i_blocks += SCOUTFS_BLOCK_SECTORS;
|
||||
|
||||
} else if (!offline && test_bit(i, map->offline)) {
|
||||
clear_bit(i, map->offline);
|
||||
scoutfs_inode_add_offline_blocks(inode, -1);
|
||||
inode->i_blocks -= SCOUTFS_BLOCK_SECTORS;
|
||||
}
|
||||
|
||||
modified = true;
|
||||
@@ -983,10 +987,13 @@ static int find_alloc_block(struct super_block *sb, struct inode *inode,
|
||||
goto out;
|
||||
|
||||
/* update the mapping */
|
||||
if (test_and_clear_bit(map_ind, map->offline))
|
||||
if (test_and_clear_bit(map_ind, map->offline)) {
|
||||
scoutfs_inode_add_offline_blocks(inode, -1);
|
||||
inode->i_blocks -= SCOUTFS_BLOCK_SECTORS;
|
||||
}
|
||||
map->blknos[map_ind] = blkno;
|
||||
scoutfs_inode_add_online_blocks(inode, 1);
|
||||
inode->i_blocks += SCOUTFS_BLOCK_SECTORS;
|
||||
|
||||
bytes = encode_mapping(map);
|
||||
scoutfs_kvec_init(val, map->encoded, bytes);
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#define SCOUTFS_BLOCK_SIZE (1 << SCOUTFS_BLOCK_SHIFT)
|
||||
#define SCOUTFS_BLOCK_MASK (SCOUTFS_BLOCK_SIZE - 1)
|
||||
#define SCOUTFS_BLOCKS_PER_PAGE (PAGE_SIZE / SCOUTFS_BLOCK_SIZE)
|
||||
#define SCOUTFS_BLOCK_SECTOR_SHIFT (SCOUTFS_BLOCK_SHIFT - 9)
|
||||
#define SCOUTFS_BLOCK_SECTORS (1 << SCOUTFS_BLOCK_SECTOR_SHIFT)
|
||||
|
||||
/*
|
||||
* FS data is stored in segments, for now they're fixed size. They'll
|
||||
@@ -464,7 +466,6 @@ struct scoutfs_timespec {
|
||||
*/
|
||||
struct scoutfs_inode {
|
||||
__le64 size;
|
||||
__le64 blocks;
|
||||
__le64 meta_seq;
|
||||
__le64 data_seq;
|
||||
__le64 data_version;
|
||||
|
||||
@@ -234,9 +234,15 @@ static void load_inode(struct inode *inode, struct scoutfs_inode *cinode)
|
||||
ci->online_blocks = le64_to_cpu(cinode->online_blocks);
|
||||
ci->offline_blocks = le64_to_cpu(cinode->offline_blocks);
|
||||
ci->next_readdir_pos = le64_to_cpu(cinode->next_readdir_pos);
|
||||
|
||||
ci->flags = le32_to_cpu(cinode->flags);
|
||||
|
||||
/*
|
||||
* i_blocks is initialized from online and offline and is then
|
||||
* maintained as blocks come and go.
|
||||
*/
|
||||
inode->i_blocks = (ci->online_blocks = + ci->offline_blocks)
|
||||
<< SCOUTFS_BLOCK_SECTOR_SHIFT;
|
||||
|
||||
set_item_info(ci, cinode);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user