mirror of
https://github.com/versity/scoutfs.git
synced 2026-01-08 04:55:21 +00:00
Add an inode data_version field
The data_version field is changed every time the contents of the file could have changed. Signed-off-by: Zach Brown <zab@versity.com> Reviewed-by: Mark Fasheh <mfasheh@versity.com>
This commit is contained in:
@@ -615,6 +615,11 @@ static int scoutfs_write_end(struct file *file, struct address_space *mapping,
|
||||
scoutfs_ino(inode), PGA(page), (u64)pos, len, copied);
|
||||
|
||||
ret = generic_write_end(file, mapping, pos, len, copied, page, fsdata);
|
||||
if (ret > 0) {
|
||||
scoutfs_inode_inc_data_version(inode);
|
||||
/* XXX kind of a big hammer, inode life cycle needs work */
|
||||
scoutfs_update_inode_item(inode);
|
||||
}
|
||||
scoutfs_release_trans(sb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -200,6 +200,10 @@ struct scoutfs_timespec {
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* @data_version: incremented every time the contents of a file could
|
||||
* have changed. It is exposed via an ioctl and is then provided as an
|
||||
* argument to data functions to protect racing modification.
|
||||
*
|
||||
* XXX
|
||||
* - otime?
|
||||
* - compat flags?
|
||||
@@ -211,6 +215,7 @@ struct scoutfs_inode {
|
||||
__le64 size;
|
||||
__le64 blocks;
|
||||
__le64 link_counter;
|
||||
__le64 data_version;
|
||||
__le32 nlink;
|
||||
__le32 uid;
|
||||
__le32 gid;
|
||||
|
||||
@@ -120,9 +120,10 @@ static void load_inode(struct inode *inode, struct scoutfs_inode *cinode)
|
||||
inode->i_mtime.tv_nsec = le32_to_cpu(cinode->mtime.nsec);
|
||||
inode->i_ctime.tv_sec = le64_to_cpu(cinode->ctime.sec);
|
||||
inode->i_ctime.tv_nsec = le32_to_cpu(cinode->ctime.nsec);
|
||||
|
||||
|
||||
ci->salt = le32_to_cpu(cinode->salt);
|
||||
atomic64_set(&ci->link_counter, le64_to_cpu(cinode->link_counter));
|
||||
ci->data_version = le64_to_cpu(cinode->data_version);
|
||||
}
|
||||
|
||||
static int scoutfs_read_locked_inode(struct inode *inode)
|
||||
@@ -148,6 +149,31 @@ static int scoutfs_read_locked_inode(struct inode *inode)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void scoutfs_inode_inc_data_version(struct inode *inode)
|
||||
{
|
||||
struct scoutfs_inode_info *si = SCOUTFS_I(inode);
|
||||
|
||||
preempt_disable();
|
||||
write_seqcount_begin(&si->seqcount);
|
||||
si->data_version++;
|
||||
write_seqcount_end(&si->seqcount);
|
||||
preempt_enable();
|
||||
}
|
||||
|
||||
u64 scoutfs_inode_get_data_version(struct inode *inode)
|
||||
{
|
||||
struct scoutfs_inode_info *si = SCOUTFS_I(inode);
|
||||
unsigned int seq;
|
||||
u64 vers;
|
||||
|
||||
do {
|
||||
seq = read_seqcount_begin(&si->seqcount);
|
||||
vers = si->data_version;
|
||||
} while (read_seqcount_retry(&si->seqcount, seq));
|
||||
|
||||
return vers;
|
||||
}
|
||||
|
||||
static int scoutfs_iget_test(struct inode *inode, void *arg)
|
||||
{
|
||||
struct scoutfs_inode_info *ci = SCOUTFS_I(inode);
|
||||
@@ -210,6 +236,7 @@ static void store_inode(struct scoutfs_inode *cinode, struct inode *inode)
|
||||
|
||||
cinode->salt = cpu_to_le32(ci->salt);
|
||||
cinode->link_counter = cpu_to_le64(atomic64_read(&ci->link_counter));
|
||||
cinode->data_version = cpu_to_le64(ci->data_version);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -366,6 +393,8 @@ struct inode *scoutfs_new_inode(struct super_block *sb, struct inode *dir,
|
||||
|
||||
ci = SCOUTFS_I(inode);
|
||||
ci->ino = ino;
|
||||
seqcount_init(&ci->seqcount);
|
||||
ci->data_version = 0;
|
||||
get_random_bytes(&ci->salt, sizeof(ci->salt));
|
||||
atomic64_set(&ci->link_counter, 0);
|
||||
|
||||
|
||||
@@ -5,6 +5,9 @@ struct scoutfs_inode_info {
|
||||
u64 ino;
|
||||
u32 salt;
|
||||
|
||||
seqcount_t seqcount;
|
||||
u64 data_version;
|
||||
|
||||
atomic64_t link_counter;
|
||||
struct rw_semaphore xattr_rwsem;
|
||||
|
||||
@@ -33,6 +36,8 @@ void scoutfs_dirty_inode(struct inode *inode, int flags);
|
||||
void scoutfs_update_inode_item(struct inode *inode);
|
||||
struct inode *scoutfs_new_inode(struct super_block *sb, struct inode *dir,
|
||||
umode_t mode, dev_t rdev);
|
||||
void scoutfs_inode_inc_data_version(struct inode *inode);
|
||||
u64 scoutfs_inode_get_data_version(struct inode *inode);
|
||||
|
||||
int scoutfs_scan_orphans(struct super_block *sb);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user