Walk stable trees in _since ioctls

The _since ioctls walk btrees and return items that are newer than a
given sequence number.  The intended behaviour is that items will
appear in a greater sequence number if they change after appearing
in the queries.  This promise doesn't hold for items that are being
modified in the current transaction.  The caller would have to always
ask for seq X + 1 after seeing seq X to make sure it got all the changes
that happened in seq X while it was the current dirty transaction.

This is fixed by having the interfaces walk the stable btrees from the
previous transaction.  The results will always be a little stale but
userspace already has to deal with stale results because it can't lock
out change, and it can use sync (and a commit age tunable we'll add) to
limit how stale the results can be.

Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
Zach Brown
2016-10-24 15:34:40 -07:00
parent 2fc1b99698
commit 165d833c46
2 changed files with 7 additions and 2 deletions

View File

@@ -44,7 +44,7 @@ static long scoutfs_ioc_inodes_since(struct file *file, unsigned long arg,
u8 type)
{
struct super_block *sb = file_inode(file)->i_sb;
struct scoutfs_btree_root *meta = SCOUTFS_META(sb);
struct scoutfs_btree_root *meta = SCOUTFS_STABLE_META(sb);
struct scoutfs_ioctl_inodes_since __user *uargs = (void __user *)arg;
struct scoutfs_ioctl_inodes_since args;
struct scoutfs_ioctl_ino_seq __user *uiseq;
@@ -218,7 +218,7 @@ static long scoutfs_ioc_find_xattr(struct file *file, unsigned long arg,
bool find_name)
{
struct super_block *sb = file_inode(file)->i_sb;
struct scoutfs_btree_root *meta = SCOUTFS_META(sb);
struct scoutfs_btree_root *meta = SCOUTFS_STABLE_META(sb);
struct scoutfs_ioctl_find_xattr args;
struct scoutfs_key key;
struct scoutfs_key last;

View File

@@ -61,6 +61,11 @@ static inline struct scoutfs_btree_root *SCOUTFS_META(struct super_block *sb)
return &SCOUTFS_SB(sb)->super.btree_root;
}
static inline struct scoutfs_btree_root *SCOUTFS_STABLE_META(struct super_block *sb)
{
return &SCOUTFS_SB(sb)->stable_super.btree_root;
}
void scoutfs_advance_dirty_super(struct super_block *sb);
int scoutfs_write_dirty_super(struct super_block *sb);