Skip to content

Commit

Permalink
fs: uninline inode_query_iversion
Browse files Browse the repository at this point in the history
Reviewed-by: NeilBrown <neilb@suse.de>
Reviewed-by: Jan Kara <jack@suse.cz>
Reviewed-by: Christian Brauner <brauner@kernel.org>
Signed-off-by: Jeff Layton <jlayton@kernel.org>
  • Loading branch information
Jeff Layton committed Jan 26, 2023
1 parent 948ef7b commit c5bc1b3
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 36 deletions.
36 changes: 36 additions & 0 deletions fs/libfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1582,3 +1582,39 @@ bool inode_maybe_inc_iversion(struct inode *inode, bool force)
return true;
}
EXPORT_SYMBOL(inode_maybe_inc_iversion);

/**
* inode_query_iversion - read i_version for later use
* @inode: inode from which i_version should be read
*
* Read the inode i_version counter. This should be used by callers that wish
* to store the returned i_version for later comparison. This will guarantee
* that a later query of the i_version will result in a different value if
* anything has changed.
*
* In this implementation, we fetch the current value, set the QUERIED flag and
* then try to swap it into place with a cmpxchg, if it wasn't already set. If
* that fails, we try again with the newly fetched value from the cmpxchg.
*/
u64 inode_query_iversion(struct inode *inode)
{
u64 cur, new;

cur = inode_peek_iversion_raw(inode);
do {
/* If flag is already set, then no need to swap */
if (cur & I_VERSION_QUERIED) {
/*
* This barrier (and the implicit barrier in the
* cmpxchg below) pairs with the barrier in
* inode_maybe_inc_iversion().
*/
smp_mb();
break;
}

new = cur | I_VERSION_QUERIED;
} while (!atomic64_try_cmpxchg(&inode->i_version, &cur, new));
return cur >> I_VERSION_QUERIED_SHIFT;
}
EXPORT_SYMBOL(inode_query_iversion);
38 changes: 2 additions & 36 deletions include/linux/iversion.h
Original file line number Diff line number Diff line change
Expand Up @@ -234,42 +234,6 @@ inode_peek_iversion(const struct inode *inode)
return inode_peek_iversion_raw(inode) >> I_VERSION_QUERIED_SHIFT;
}

/**
* inode_query_iversion - read i_version for later use
* @inode: inode from which i_version should be read
*
* Read the inode i_version counter. This should be used by callers that wish
* to store the returned i_version for later comparison. This will guarantee
* that a later query of the i_version will result in a different value if
* anything has changed.
*
* In this implementation, we fetch the current value, set the QUERIED flag and
* then try to swap it into place with a cmpxchg, if it wasn't already set. If
* that fails, we try again with the newly fetched value from the cmpxchg.
*/
static inline u64
inode_query_iversion(struct inode *inode)
{
u64 cur, new;

cur = inode_peek_iversion_raw(inode);
do {
/* If flag is already set, then no need to swap */
if (cur & I_VERSION_QUERIED) {
/*
* This barrier (and the implicit barrier in the
* cmpxchg below) pairs with the barrier in
* inode_maybe_inc_iversion().
*/
smp_mb();
break;
}

new = cur | I_VERSION_QUERIED;
} while (!atomic64_try_cmpxchg(&inode->i_version, &cur, new));
return cur >> I_VERSION_QUERIED_SHIFT;
}

/*
* For filesystems without any sort of change attribute, the best we can
* do is fake one up from the ctime:
Expand All @@ -283,6 +247,8 @@ static inline u64 time_to_chattr(struct timespec64 *t)
return chattr;
}

u64 inode_query_iversion(struct inode *inode);

/**
* inode_eq_iversion_raw - check whether the raw i_version counter has changed
* @inode: inode to check
Expand Down

0 comments on commit c5bc1b3

Please sign in to comment.