mirror of
https://github.com/versity/scoutfs.git
synced 2026-09-16 13:04:13 +00:00
scoutfs: add atomic online/offline blocks calls
Add functions that atomically change and query the online and offline block counts as a pair. They're semantically linked and we shouldn't present counts that don't match if they're in the process of being updated. Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
@@ -30,6 +30,7 @@
|
||||
EXPAND_COUNTER(corrupt_dirent_backref_name_len) \
|
||||
EXPAND_COUNTER(corrupt_dirent_name_len) \
|
||||
EXPAND_COUNTER(corrupt_dirent_readdir_name_len) \
|
||||
EXPAND_COUNTER(corrupt_inode_block_counts) \
|
||||
EXPAND_COUNTER(corrupt_symlink_inode_size) \
|
||||
EXPAND_COUNTER(corrupt_symlink_missing_item) \
|
||||
EXPAND_COUNTER(corrupt_symlink_not_null_term) \
|
||||
|
||||
@@ -658,6 +658,7 @@ enum {
|
||||
SC_SYMLINK_NOT_NULL_TERM,
|
||||
SC_BTREE_BLOCK_LEVEL,
|
||||
SC_BTREE_NO_CHILD_REF,
|
||||
SC_INODE_BLOCK_COUNTS,
|
||||
SC_NR_SOURCES,
|
||||
};
|
||||
|
||||
|
||||
+39
-23
@@ -500,32 +500,32 @@ void scoutfs_inode_inc_data_version(struct inode *inode)
|
||||
preempt_enable();
|
||||
}
|
||||
|
||||
static void add_seq_value(struct scoutfs_inode_info *si, u64 *si_u64, u64 val)
|
||||
{
|
||||
preempt_disable();
|
||||
write_seqcount_begin(&si->seqcount);
|
||||
*si_u64 += val;
|
||||
write_seqcount_end(&si->seqcount);
|
||||
preempt_enable();
|
||||
}
|
||||
|
||||
void scoutfs_inode_add_online_blocks(struct inode *inode, u64 val)
|
||||
void scoutfs_inode_add_onoff(struct inode *inode, s64 on, s64 off)
|
||||
{
|
||||
struct scoutfs_inode_info *si;
|
||||
|
||||
if (inode) {
|
||||
if (inode && (on || off)) {
|
||||
si = SCOUTFS_I(inode);
|
||||
add_seq_value(si, &SCOUTFS_I(inode)->online_blocks, val);
|
||||
}
|
||||
}
|
||||
preempt_disable();
|
||||
write_seqcount_begin(&si->seqcount);
|
||||
|
||||
void scoutfs_inode_add_offline_blocks(struct inode *inode, u64 val)
|
||||
{
|
||||
struct scoutfs_inode_info *si;
|
||||
/* inode and extents out of sync, bad callers */
|
||||
if (((s64)si->online_blocks + on < 0) ||
|
||||
((s64)si->offline_blocks + off < 0)) {
|
||||
scoutfs_corruption(inode->i_sb, SC_INODE_BLOCK_COUNTS,
|
||||
corrupt_inode_block_counts,
|
||||
"ino %llu size %llu online %llu + %lld offline %llu + %lld",
|
||||
scoutfs_ino(inode), i_size_read(inode),
|
||||
si->online_blocks, on, si->offline_blocks, off);
|
||||
}
|
||||
|
||||
if (inode) {
|
||||
si = SCOUTFS_I(inode);
|
||||
add_seq_value(si, &SCOUTFS_I(inode)->offline_blocks, val);
|
||||
si->online_blocks += on;
|
||||
si->offline_blocks += off;
|
||||
/* XXX not sure if this is right */
|
||||
inode->i_blocks += (on + off) * SCOUTFS_BLOCK_SECTORS;
|
||||
|
||||
write_seqcount_end(&si->seqcount);
|
||||
preempt_enable();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -577,6 +577,19 @@ u64 scoutfs_inode_offline_blocks(struct inode *inode)
|
||||
|
||||
return read_seqcount_u64(inode, &si->offline_blocks);
|
||||
}
|
||||
|
||||
void scoutfs_inode_get_onoff(struct inode *inode, s64 *on, s64 *off)
|
||||
{
|
||||
struct scoutfs_inode_info *si = SCOUTFS_I(inode);
|
||||
unsigned int seq;
|
||||
|
||||
do {
|
||||
seq = read_seqcount_begin(&si->seqcount);
|
||||
*on = SCOUTFS_I(inode)->online_blocks;
|
||||
*off = SCOUTFS_I(inode)->offline_blocks;
|
||||
} while (read_seqcount_retry(&si->seqcount, seq));
|
||||
}
|
||||
|
||||
static int scoutfs_iget_test(struct inode *inode, void *arg)
|
||||
{
|
||||
struct scoutfs_inode_info *ci = SCOUTFS_I(inode);
|
||||
@@ -644,6 +657,10 @@ out:
|
||||
static void store_inode(struct scoutfs_inode *cinode, struct inode *inode)
|
||||
{
|
||||
struct scoutfs_inode_info *ci = SCOUTFS_I(inode);
|
||||
u64 online_blocks;
|
||||
u64 offline_blocks;
|
||||
|
||||
scoutfs_inode_get_onoff(inode, &online_blocks, &offline_blocks);
|
||||
|
||||
cinode->size = cpu_to_le64(i_size_read(inode));
|
||||
cinode->nlink = cpu_to_le32(inode->i_nlink);
|
||||
@@ -661,9 +678,8 @@ static void store_inode(struct scoutfs_inode *cinode, struct inode *inode)
|
||||
cinode->meta_seq = cpu_to_le64(scoutfs_inode_meta_seq(inode));
|
||||
cinode->data_seq = cpu_to_le64(scoutfs_inode_data_seq(inode));
|
||||
cinode->data_version = cpu_to_le64(scoutfs_inode_data_version(inode));
|
||||
cinode->online_blocks = cpu_to_le64(scoutfs_inode_online_blocks(inode));
|
||||
cinode->offline_blocks =
|
||||
cpu_to_le64(scoutfs_inode_offline_blocks(inode));
|
||||
cinode->online_blocks = cpu_to_le64(online_blocks);
|
||||
cinode->offline_blocks = cpu_to_le64(offline_blocks);
|
||||
cinode->next_readdir_pos = cpu_to_le64(ci->next_readdir_pos);
|
||||
cinode->next_xattr_id = cpu_to_le64(ci->next_xattr_id);
|
||||
cinode->flags = cpu_to_le32(ci->flags);
|
||||
|
||||
@@ -102,11 +102,13 @@ void scoutfs_inode_set_data_seq(struct inode *inode);
|
||||
void scoutfs_inode_inc_data_version(struct inode *inode);
|
||||
void scoutfs_inode_add_online_blocks(struct inode *inode, u64 val);
|
||||
void scoutfs_inode_add_offline_blocks(struct inode *inode, u64 val);
|
||||
void scoutfs_inode_add_onoff(struct inode *inode, s64 on, s64 off);
|
||||
u64 scoutfs_inode_meta_seq(struct inode *inode);
|
||||
u64 scoutfs_inode_data_seq(struct inode *inode);
|
||||
u64 scoutfs_inode_data_version(struct inode *inode);
|
||||
u64 scoutfs_inode_online_blocks(struct inode *inode);
|
||||
u64 scoutfs_inode_offline_blocks(struct inode *inode);
|
||||
void scoutfs_inode_get_onoff(struct inode *inode, s64 *on, s64 *off);
|
||||
int scoutfs_complete_truncate(struct inode *inode, struct scoutfs_lock *lock);
|
||||
|
||||
int scoutfs_inode_refresh(struct inode *inode, struct scoutfs_lock *lock,
|
||||
|
||||
+1
-2
@@ -464,8 +464,7 @@ static long scoutfs_ioc_stat_more(struct file *file, unsigned long arg)
|
||||
stm.meta_seq = scoutfs_inode_meta_seq(inode);
|
||||
stm.data_seq = scoutfs_inode_data_seq(inode);
|
||||
stm.data_version = scoutfs_inode_data_version(inode);
|
||||
stm.online_blocks = scoutfs_inode_online_blocks(inode);
|
||||
stm.offline_blocks = scoutfs_inode_offline_blocks(inode);
|
||||
scoutfs_inode_get_onoff(inode, &stm.online_blocks, &stm.offline_blocks);
|
||||
|
||||
if (copy_to_user((void __user *)arg, &stm, stm.valid_bytes))
|
||||
return -EFAULT;
|
||||
|
||||
Reference in New Issue
Block a user