diff --git a/kmod/src/data.c b/kmod/src/data.c index bae06b3c..16f3b20e 100644 --- a/kmod/src/data.c +++ b/kmod/src/data.c @@ -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); diff --git a/kmod/src/format.h b/kmod/src/format.h index bb8d674a..99241394 100644 --- a/kmod/src/format.h +++ b/kmod/src/format.h @@ -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; diff --git a/kmod/src/inode.c b/kmod/src/inode.c index 2146ed9c..965afbde 100644 --- a/kmod/src/inode.c +++ b/kmod/src/inode.c @@ -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); }